pax_global_header00006660000000000000000000000064130726473060014522gustar00rootroot0000000000000052 comment=c98c08f78c6f35e9009afad170a5e48a1b0563ff trayer-srg-trayer-1.1.7/000077500000000000000000000000001307264730600151335ustar00rootroot00000000000000trayer-srg-trayer-1.1.7/.gitignore000066400000000000000000000000521307264730600171200ustar00rootroot00000000000000Makefile.config config.h *.o *.dep trayer trayer-srg-trayer-1.1.7/CHANGELOG000066400000000000000000000065571307264730600163620ustar00rootroot00000000000000trayer changelog 1.1.7 * Library cleanup * Icon Spacing 1.1.6 * react on monitor setup changes 1.1.5 * Replace deprecated functions from gdk * Fix panel width default value * Manual updates 1.1.4 * Update cmdline help * Restore padding functionality * Add primary monitor cmdline flag 1.1.3 * Minimal height restriction * Build process fixes 1.1.2 * Type fixes. 1.1.1 * Remove unusable features from legacy code * Replace hand written X event handling with gdk functions 1.1 * multi monitor support * add distancefrom parameter * remove plugin handling code / code cleanup 1.0 * tray code extracted from the main fbpanel sources * configuration using config file changed into command-line options * positionx and positiony options removed * distance option added ----------------------------------------------------------------------------- fbpanel changes follow ----------------------------------------------------------------------------- 3.8 * warnings clean-up * X11 memory leacher was fixed * taskbar can be set to show only mapped/iconified and wins from other desktops * transparency initial support * gtkbar was ported to gtk2, so fbpanel is compiled with GTK_DISABLE_DEPRECETED * initial dll support 3.7 * rounded corners (optional) * taskbar view fix 3.6 * taskbar icon size fix * menu icon size fix * pager checks for drawable pixmap 3.5 * Drag-n-Drop for launchbar * menu plugin * removed limith for max task size in taskbar 3.4 * gtk2.2 linkage fix * strut fix * launchbar segfault on wrong config fix * '&' at the end of action var in launchbar config is depreciated 3.3 * taskbar icon size fix 3.2 * scroll mouse in pager changes desktops * packaging and makefiles now are ready for system wide install additionally ./configure was implemented * systray checks for another tray already running 3.1 * improving icon quility in taskbar * system tray (aka notification area) support * NET_WM_STRUT_PARTIAL and NET_WM_STRUT were implmented * taskbar update icon image on every icon change 3.0 * official version bump :-) 3.0-rc-1 * porting to GTK2+. port is based on phako's patch "[ 678749 ] make it compile and work with gtk2" 2.2 * support for XEmbed docklets via gtktray utility 2.1 * tray plugin was written * documentation update * web site update 2.0 * complete engine rewrite * new plugin API * pager fixes 1.4 * bug-fixes for pager plugin 1.3 * middle-click in taskbar will toggle shaded state of a window * added image plugin - this is simple plugin that just shows an image * pager eye-candy fixes * close_module function update 1.2 * we've got new module - pager! Yeeaa-Haa!! * segfault on wrong config file was fixed 1.1 * parsing engine was rewritten * modules' static variables were converted to mallocs * configurable size and postion of a panel * ability to specify what modules to load * '~' is accepted in config files * 1.0 * 1.0-rc2 was released as 1.0 1.0-rc2 * taskbar config file was added an option to switch tooltips on/off * added tooltips to taskbar (thanks to Joe MacDonald joe@deserted.net) 1.0-rc1 * copyright comments were changed 1.0-rc0 * added _NET_WM_STRUT support * panel now is unfocusable. this fixes iconify bug under sawfish * panel's height is calculated at run-time, instead of fixed 22 0.11 * improved EWMH/NETWM support * added openbox support * added clock customization (thanks to Tooar tooar@gmx.net) * README was rewrited * bug fixes trayer-srg-trayer-1.1.7/COPYING000066400000000000000000000021611307264730600161660ustar00rootroot00000000000000Copyright (C) 2005 Maciej "harnir" Delmanowski Copyright (C) 2002 Anatoly Asviyan (aka Arsen) Copyright (C) 2000 Peter Zelezny Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Soft- ware"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following condi- tions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. trayer-srg-trayer-1.1.7/CREDITS000066400000000000000000000017561307264730600161640ustar00rootroot00000000000000Thanks goes to: - Grzegorz Niewêg³owski - code extraction from fbpanel - Rafal Bisingier - conversion of configuration using ~/.fbpanel/* files to commandline options - Thomas Rydzynski - added new option 'distance' fbpanel credits follow ----------------------------------------------------------------------------- I'd like to thank to GNOME project. I learn a lot from its code and some pieces were used in fbpanel. Correct for version 3.0, systray code and wm icon code were copied from GNOME Credits to all people who contributed by writing code and solving bugs. Joe MacDonald Jens Georg and others Credits and lot of thanks to Peter Zelezny an author of fspanel (see http://www.chatjunkies.org/fspanel/ or http://freshmeat.net/projects/fspanel/) The first version of fBpanel was started as hacking around fSpanel :-) trayer-srg-trayer-1.1.7/INSTALL000066400000000000000000000003401307264730600161610ustar00rootroot00000000000000Installation: 1. Default way Most users (99.99%) should use this way :-) ./configure make su - make install 2. Litle customization Run ./configure --help to see supported options, then goto step 1 trayer-srg-trayer-1.1.7/Makefile000066400000000000000000000012611307264730600165730ustar00rootroot00000000000000# Part 0 # load common stuff TOPDIR = . include $(TOPDIR)/Makefile.common # Part 1 # recursive make SRC = panel.c misc.c bg.c eggtraymanager.c eggmarshalers.c fixedtip.c main.c gdk-helper.c OBJ = $(SRC:%.c=%.o) DEP = $(SRC:%.c=%.dep) ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),distclean) -include $(DEP) endif endif TARGET = trayer $(TARGET): $(OBJ) $(CC) $(LDFLAGS) $(OBJ) -o $@ $(LIBS) ifeq (,$(DEVEL)) strip $@ endif all: $(TARGET) clean: $(RM) $(TARGET) $(OBJ) $(DEP) *~ distclean: rm -f Makefile.config config.h install: install -d $(DESTDIR)$(PREFIX)/bin install -m 755 $(TARGET) $(DESTDIR)$(PREFIX)/bin uninstall: rm -f $(DESTDIR)$(PREFIX)/bin/$(TARGET) trayer-srg-trayer-1.1.7/Makefile.common000066400000000000000000000012661307264730600200670ustar00rootroot00000000000000ifeq (,$(TOPDIR)) $(error TOPDIR variable must be defined) endif all: $(TOPDIR)/Makefile.config: $(error Please run $(TOPDIR)/configure first) ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),distclean) ifneq ($(MAKECMDGOALS),tar) -include $(TOPDIR)/Makefile.config endif endif endif CC ?= gcc PKG_CONFIG ?= pkg-config LIBS = $(shell $(PKG_CONFIG) --libs gtk+-2.0 gdk-pixbuf-2.0 x11) INCS = $(shell $(PKG_CONFIG) --cflags gtk+-2.0 gdk-pixbuf-2.0 x11) CFLAGS ?= -O2 -Wall ifneq (,$(DEVEL)) CFLAGS ?= -g -Wall endif %.o: %.c $(CC) $(CFLAGS) $(INCS) -c $< %.dep: %.c $(CC) $(CFLAGS) $(INCS) -MM $< -o $@ .PHONY: all clean distclean install uninstall distclean: clean install: all trayer-srg-trayer-1.1.7/README000066400000000000000000000077261307264730600160270ustar00rootroot00000000000000 trayer-srg NAME trayer-srg is a lightweight GTK2-based systray for UNIX desktop SYNOPSYS trayer [OPTION]... DESCRIPTION trayer-srg was forked from trayer in january 2010 to add some fancy features and clean up code. trayer is small program designed to provide systray functionality present in GNOME/KDE desktop enviroments for window managers which doesn't support that function. It's similar to other applications such as 'peksystray' and 'docker'. trayer code was extracted from fbpanel application, you can find more about it on it's homepage: http://fbpanel.sourceforge.net/ You can find new versions of trayer and support on FVWM-Crystal project homepage: http://fvwm-crystal.berlios.de/ You can find code of trayer-srg on his github page: http://github.com/sargon/trayer-srg OPTIONS -h - prints help message and exits -v - prints version and exits --edge - screen edge to use --align - alignment --margin - length of margin in pixels --distance - space between trayer's window and screen edge --distancefrom - Specifies which edge to calculate distance from, see above. --widthtype - how panel width is calculated: request - follow widgets' size requests. can shrink or grow dynamically pixel - ocupy fixed number of pixels, then 'width' variable holds a number percent - be 'width' precent of an edge --width - width of a panel (not used with --widthtype=request) --heighttype - how panel height is calcilated: pixel - ocupy fixed number of pixels, then 'height' variable holds a number --height - height of a panel in pixels --SetDockTpe - Identify panel window type as dock --SetPartialStrut - Reserve panel's space so that it will not be covered by maximazied windows --transparent - use transparency --tint - color used to "tint" background wallpaper with --alpha - pocentage of transparency <0-256> --expand - specifies if trayer can accomodate extra space or not --padding - extra space between trayer's window frame and docked icons --monitor - define the mointor on which you like trayer to appear, number of zero to number of monitors minus one, or the string "primary". --iconspacing - Space between tray icons in pixels. TRAYER IN DISTROS debian https://packages.debian.org/source/jessie/trayer ubuntu http://packages.ubuntu.com/xenial/trayer archlinux https://aur.archlinux.org/packages/trayer-srg-git/ gentoo http://packages.gentoo.org/package/x11-misc/trayer-srg nixos http://hydra.nixos.org/job/nixpkgs/trunk/trayer.i686-linux/latest http://hydra.nixos.org/job/nixpkgs/trunk/trayer.x86_64-linux/latest AUTHORS Maciej Delmanowski Anatoly Asviyan - fbpanel Rafal Bisingier - conversion of configuration using ~/.fbpanel/* files to commandline options Grzegorz Niewêg³owski - code extraction from fbpanel Thomas Rydzynski - added new option 'distance' Keegan Carruthers-Smith - fix align Yury Akudovich - added new option distancefrom option Jens Peter Secher - various (debian trayer fork) Daniel Ehlers - multi monitor support, code cleanup Stu Black - help closing a problem with wrong values in _NET_WM_STRUT_PARTIAL Michael Weber - fix build problems, improvements cmdline parameter handling Johannes Bittner - primary switch for monitor selection Vladimir Murzin - fixing transparency startup problem Corey Richardson - Found some default value fuckup Constantine Verutin - React on changes in monitor setup. Robbie Harwood - Fixup build Omar Sandoval - Fixups Harri Nieminen - Fixup library linking trayer-srg-trayer-1.1.7/TODO000066400000000000000000000003021307264730600156160ustar00rootroot00000000000000TODO ==== REDUCE ------ + clean up code FANCY ----- + background color selectable + review image resizing + (code) documentation - increase maintainbility + tray icon rendering trayer-srg-trayer-1.1.7/bg.c000066400000000000000000000114431307264730600156720ustar00rootroot00000000000000 #include #include #include #include #include #include #include #include #include #include #include #include "bg.h" #include "dbg.h" #include "config.h" static Display *dpy; //static int screen; static Window xroot; static Pixmap xrootbg = 0xc046ad; static GC gc; static Atom id = 0; static Pixmap bg_get_root_bg() { Pixmap ret; ENTER; ret = None; if (id) { int act_format, c = 2 ; u_long nitems ; u_long bytes_after ; u_char *prop ; Atom dummy_id; do { if (XGetWindowProperty(dpy, xroot, id, 0, 1, False, XA_PIXMAP, &dummy_id, &act_format, &nitems, &bytes_after, &prop) == Success) { if (prop) { ret = *((Pixmap *)prop); XFree(prop); break; } } } while (--c > 0); } //fprintf(stderr, "_XROOTPMAP_ID = 0x%x\n", ret); RET(ret); } GdkPixmap * bg_new_for_win(Window win) { Window dummy; Pixmap bgpix; GdkPixmap *gbgpix; unsigned int width, height ; unsigned int border, depth; int x, y; ENTER; XGetGeometry(dpy, win, &dummy, &x, &y, &width, &height, &border, &depth); XTranslateCoordinates(dpy, win, xroot, 0, 0, &x, &y, &dummy); gbgpix = gdk_pixmap_new(NULL, width, height, depth); if (!gbgpix) RET(NULL); bgpix = gdk_x11_drawable_get_xid(gbgpix); XSetTSOrigin(dpy, gc, -x, -y) ; XFillRectangle(dpy, bgpix, gc, 0, 0, width, height); RET(gbgpix); } void bg_init(Display *dpyn) { XGCValues gcv; uint mask; ENTER; dpy = dpyn; id = XInternAtom(dpy, "_XROOTPMAP_ID", False); xroot = DefaultRootWindow(dpy); xrootbg = bg_get_root_bg(); gcv.ts_x_origin = 0; gcv.ts_y_origin = 0; gcv.fill_style = FillTiled; mask = GCTileStipXOrigin | GCTileStipYOrigin | GCFillStyle; if (xrootbg) { gcv.tile = xrootbg; mask |= GCTile ; } gc = XCreateGC (dpy, xroot, mask, &gcv) ; RET(); } void bg_rootbg_changed() { ENTER; xrootbg = bg_get_root_bg(); if (xrootbg != None) { XGCValues gcv; gcv.tile = xrootbg; XChangeGC(dpy, gc, GCTile, &gcv); DBG("changed\n"); } RET(); } void bg_close() { ENTER; XFreeGC(dpy, gc); RET(); } void modify_drawable(GdkDrawable *base, GdkGC *gc, guint32 tintcolor, gint alpha) { int w, h; GdkPixbuf *ret, *ret2; static GdkColormap *cmap = NULL; ENTER; gdk_drawable_get_size (base, &w, &h); if (!cmap) { cmap = gdk_colormap_get_system (); } ret = gdk_pixbuf_get_from_drawable (NULL, base, cmap, 0, 0, 0, 0, w, h); if (!ret) RET(); ret2 = gdk_pixbuf_composite_color_simple(ret, w, h, GDK_INTERP_HYPER, alpha, MIN(w, h), tintcolor, tintcolor); //gdk_pixbuf_render_to_drawable (ret2, base, gc, 0, 0, 0, 0, w, h, GDK_RGB_DITHER_NONE, 0, 0); gdk_draw_pixbuf (base, gc, ret2, 0, 0, 0, 0, w, h, GDK_RGB_DITHER_NONE, 0, 0); g_object_unref(ret); g_object_unref(ret2); RET(); } #ifdef TRANSPARENCY #include #include #include #include #include typedef struct _GdkWindowPaint GdkWindowPaint; struct _GdkWindowPaint { GdkRegion *region; GdkPixmap *pixmap; gint x_offset; gint y_offset; }; GdkGC * gdk_window_get_bg_gc (GdkWindow *window, GdkWindowPaint *paint) { GdkWindowObject *private = (GdkWindowObject *)window; guint gc_mask = 0; GdkGCValues gc_values; ENTER; if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent) { GdkWindowPaint tmp_paint = *paint; tmp_paint.x_offset += private->x; tmp_paint.y_offset += private->y; return gdk_window_get_bg_gc (GDK_WINDOW (private->parent), &tmp_paint); } else if (private->bg_pixmap && private->bg_pixmap != GDK_PARENT_RELATIVE_BG && private->bg_pixmap != GDK_NO_BG) { gc_values.fill = GDK_TILED; gc_values.tile = private->bg_pixmap; gc_values.ts_x_origin = -paint->x_offset; gc_values.ts_y_origin = -paint->y_offset; gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN; DBG("x_offset=%d y_offset=%d\n", paint->x_offset, paint->y_offset); return gdk_gc_new_with_values (paint->pixmap, &gc_values, gc_mask); } else { GdkGC *gc = _gdk_drawable_get_scratch_gc (paint->pixmap, FALSE); gdk_gc_set_foreground (gc, &(private->bg_color)); return g_object_ref (gc); } } #endif trayer-srg-trayer-1.1.7/bg.h000066400000000000000000000005261307264730600156770ustar00rootroot00000000000000#ifndef _BG_H_ #define _BG_H_ #include #include #include #include #include #include void bg_init(); void bg_rootbg_changed(); GdkPixmap *bg_new_for_win(Window win); void modify_drawable(GdkDrawable *base, GdkGC *gc, guint32 tintcolor, gint alpha); #endif trayer-srg-trayer-1.1.7/configure000077500000000000000000000007531307264730600170470ustar00rootroot00000000000000#!/usr/bin/env bash PREFIX=/usr if [ ! -z "$1" ]; then if [[ "$1" =~ ^--prefix= ]]; then PREFIX=$(echo $1 | cut -d= -f2) else echo "Usage: $0 [--prefix=]" exit 1 fi fi if [ -f config.h ]; then echo "overwriting old config.h..." fi cat > config.h < Makefile.config < #define ERR(fmt, args...) fprintf(stderr, fmt, ## args) #define DBG2(fmt, args...) fprintf(stderr, "%s:%-5d: " fmt, __FUNCTION__, __LINE__, ## args) #define ENTER2 do { fprintf(stderr, "%s:%-5d: ENTER\n", __FUNCTION__, __LINE__); } while(0) #define RET2(args...) do { fprintf(stderr, "%s:%-5d: RETURN\n", __FUNCTION__, __LINE__);\ return args; } while(0) //#define DBG #ifdef DBG #define ENTER do { fprintf(stderr, "%s:%-5d: ENTER\n", __FUNCTION__, __LINE__); } while(0) #define RET(args...) do { fprintf(stderr, "%s:%-5d: RETURN\n", __FUNCTION__, __LINE__);\ return args; } while(0) #define DBG(fmt, args...) fprintf(stderr, "%s:%-5d: " fmt, __FUNCTION__, __LINE__, ## args) #else #define ENTER do { } while(0) #define RET(args...) return args; #define DBG(fmt, args...) do { } while(0) #endif trayer-srg-trayer-1.1.7/eggmarshalers.c000066400000000000000000000157131307264730600201320ustar00rootroot00000000000000 #include #ifdef G_ENABLE_DEBUG #define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) #define g_marshal_value_peek_char(v) g_value_get_char (v) #define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) #define g_marshal_value_peek_int(v) g_value_get_int (v) #define g_marshal_value_peek_uint(v) g_value_get_uint (v) #define g_marshal_value_peek_long(v) g_value_get_long (v) #define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) #define g_marshal_value_peek_int64(v) g_value_get_int64 (v) #define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) #define g_marshal_value_peek_enum(v) g_value_get_enum (v) #define g_marshal_value_peek_flags(v) g_value_get_flags (v) #define g_marshal_value_peek_float(v) g_value_get_float (v) #define g_marshal_value_peek_double(v) g_value_get_double (v) #define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) #define g_marshal_value_peek_param(v) g_value_get_param (v) #define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) #define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) #define g_marshal_value_peek_object(v) g_value_get_object (v) #else /* !G_ENABLE_DEBUG */ /* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. * Do not access GValues directly in your code. Instead, use the * g_value_get_*() functions */ #define g_marshal_value_peek_boolean(v) (v)->data[0].v_int #define g_marshal_value_peek_char(v) (v)->data[0].v_int #define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint #define g_marshal_value_peek_int(v) (v)->data[0].v_int #define g_marshal_value_peek_uint(v) (v)->data[0].v_uint #define g_marshal_value_peek_long(v) (v)->data[0].v_long #define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong #define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 #define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 #define g_marshal_value_peek_enum(v) (v)->data[0].v_int #define g_marshal_value_peek_flags(v) (v)->data[0].v_uint #define g_marshal_value_peek_float(v) (v)->data[0].v_float #define g_marshal_value_peek_double(v) (v)->data[0].v_double #define g_marshal_value_peek_string(v) (v)->data[0].v_pointer #define g_marshal_value_peek_param(v) (v)->data[0].v_pointer #define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer #define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer #define g_marshal_value_peek_object(v) (v)->data[0].v_pointer #endif /* !G_ENABLE_DEBUG */ /* VOID:OBJECT,OBJECT (eggmarshalers.list:1) */ void _egg_marshal_VOID__OBJECT_OBJECT (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_VOID__OBJECT_OBJECT callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_object (param_values + 1), g_marshal_value_peek_object (param_values + 2), data2); } /* VOID:OBJECT,STRING,LONG,LONG (eggmarshalers.list:2) */ void _egg_marshal_VOID__OBJECT_STRING_LONG_LONG (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__OBJECT_STRING_LONG_LONG) (gpointer data1, gpointer arg_1, gpointer arg_2, glong arg_3, glong arg_4, gpointer data2); register GMarshalFunc_VOID__OBJECT_STRING_LONG_LONG callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 5); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__OBJECT_STRING_LONG_LONG) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_object (param_values + 1), g_marshal_value_peek_string (param_values + 2), g_marshal_value_peek_long (param_values + 3), g_marshal_value_peek_long (param_values + 4), data2); } /* VOID:OBJECT,LONG (eggmarshalers.list:3) */ void _egg_marshal_VOID__OBJECT_LONG (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__OBJECT_LONG) (gpointer data1, gpointer arg_1, glong arg_2, gpointer data2); register GMarshalFunc_VOID__OBJECT_LONG callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__OBJECT_LONG) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_object (param_values + 1), g_marshal_value_peek_long (param_values + 2), data2); } trayer-srg-trayer-1.1.7/eggmarshalers.h000066400000000000000000000030061307264730600201270ustar00rootroot00000000000000#include /* VOID:OBJECT,OBJECT (eggmarshalers.list:1) */ void _egg_marshal_VOID__OBJECT_OBJECT (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* VOID:OBJECT,STRING,LONG,LONG (eggmarshalers.list:2) */ void _egg_marshal_VOID__OBJECT_STRING_LONG_LONG (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* VOID:OBJECT,LONG (eggmarshalers.list:3) */ void _egg_marshal_VOID__OBJECT_LONG (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); trayer-srg-trayer-1.1.7/eggtraymanager.c000066400000000000000000000365411307264730600203050ustar00rootroot00000000000000/* eggtraymanager.c * Copyright (C) 2002 Anders Carlsson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include "eggtraymanager.h" #include "eggmarshalers.h" #include "panel.h" #include "gdk-helper.h" /* Signals */ enum { TRAY_ICON_ADDED, TRAY_ICON_REMOVED, MESSAGE_SENT, MESSAGE_CANCELLED, LOST_SELECTION, LAST_SIGNAL }; typedef struct { long id, len; long remaining_len; long timeout; Window window; char *str; } PendingMessage; static GObjectClass *parent_class = NULL; static guint manager_signals[LAST_SIGNAL] = { 0 }; #define SYSTEM_TRAY_REQUEST_DOCK 0 #define SYSTEM_TRAY_BEGIN_MESSAGE 1 #define SYSTEM_TRAY_CANCEL_MESSAGE 2 static gboolean egg_tray_manager_check_running_xscreen (Screen *xscreen); static void egg_tray_manager_init (EggTrayManager *manager); static void egg_tray_manager_class_init (EggTrayManagerClass *klass); static void egg_tray_manager_finalize (GObject *object); static void egg_tray_manager_unmanage (EggTrayManager *manager); GType egg_tray_manager_get_type (void) { static GType our_type = 0; if (our_type == 0) { static const GTypeInfo our_info = { sizeof (EggTrayManagerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) egg_tray_manager_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (EggTrayManager), 0, /* n_preallocs */ (GInstanceInitFunc) egg_tray_manager_init }; our_type = g_type_register_static (G_TYPE_OBJECT, "EggTrayManager", &our_info, 0); } return our_type; } static void egg_tray_manager_init (EggTrayManager *manager) { manager->socket_table = g_hash_table_new (NULL, NULL); } static void egg_tray_manager_class_init (EggTrayManagerClass *klass) { GObjectClass *gobject_class; parent_class = g_type_class_peek_parent (klass); gobject_class = (GObjectClass *)klass; gobject_class->finalize = egg_tray_manager_finalize; manager_signals[TRAY_ICON_ADDED] = g_signal_new ("tray_icon_added", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EggTrayManagerClass, tray_icon_added), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GTK_TYPE_SOCKET); manager_signals[TRAY_ICON_REMOVED] = g_signal_new ("tray_icon_removed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EggTrayManagerClass, tray_icon_removed), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GTK_TYPE_SOCKET); manager_signals[MESSAGE_SENT] = g_signal_new ("message_sent", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EggTrayManagerClass, message_sent), NULL, NULL, _egg_marshal_VOID__OBJECT_STRING_LONG_LONG, G_TYPE_NONE, 4, GTK_TYPE_SOCKET, G_TYPE_STRING, G_TYPE_LONG, G_TYPE_LONG); manager_signals[MESSAGE_CANCELLED] = g_signal_new ("message_cancelled", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EggTrayManagerClass, message_cancelled), NULL, NULL, _egg_marshal_VOID__OBJECT_LONG, G_TYPE_NONE, 2, GTK_TYPE_SOCKET, G_TYPE_LONG); manager_signals[LOST_SELECTION] = g_signal_new ("lost_selection", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EggTrayManagerClass, lost_selection), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } static void egg_tray_manager_finalize (GObject *object) { EggTrayManager *manager; manager = EGG_TRAY_MANAGER (object); egg_tray_manager_unmanage (manager); G_OBJECT_CLASS (parent_class)->finalize (object); } EggTrayManager * egg_tray_manager_new (void) { EggTrayManager *manager; manager = g_object_new (EGG_TYPE_TRAY_MANAGER, NULL); return manager; } static gboolean egg_tray_manager_plug_removed (GtkSocket *socket, EggTrayManager *manager) { Window *window; window = g_object_get_data (G_OBJECT (socket), "egg-tray-child-window"); g_hash_table_remove (manager->socket_table, GINT_TO_POINTER (*window)); g_object_set_data (G_OBJECT (socket), "egg-tray-child-window", NULL); g_signal_emit (manager, manager_signals[TRAY_ICON_REMOVED], 0, socket); /* This destroys the socket. */ return FALSE; } static void egg_tray_manager_handle_dock_request (EggTrayManager *manager, XClientMessageEvent *xevent) { GtkWidget *socket; Window *window; socket = gtk_socket_new (); /* We need to set the child window here * so that the client can call _get functions * in the signal handler */ window = g_new (Window, 1); *window = xevent->data.l[2]; g_object_set_data_full (G_OBJECT (socket), "egg-tray-child-window", window, g_free); g_signal_emit (manager, manager_signals[TRAY_ICON_ADDED], 0, socket); /* Add the socket only if it's been attached */ if (GTK_IS_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (socket)))) { g_signal_connect (socket, "plug_removed", G_CALLBACK (egg_tray_manager_plug_removed), manager); gtk_socket_add_id (GTK_SOCKET (socket), xevent->data.l[2]); g_hash_table_insert (manager->socket_table, GINT_TO_POINTER (xevent->data.l[2]), socket); } else gtk_widget_destroy (socket); } static void pending_message_free (PendingMessage *message) { g_free (message->str); g_free (message); } static void egg_tray_manager_handle_message_data (EggTrayManager *manager, XClientMessageEvent *xevent) { GList *p; int len; /* Try to see if we can find the * pending message in the list */ for (p = manager->messages; p; p = p->next) { PendingMessage *msg = p->data; if (xevent->window == msg->window) { /* Append the message */ len = MIN (msg->remaining_len, 20); memcpy ((msg->str + msg->len - msg->remaining_len), &xevent->data, len); msg->remaining_len -= len; if (msg->remaining_len == 0) { GtkSocket *socket; socket = g_hash_table_lookup (manager->socket_table, GINT_TO_POINTER (msg->window)); if (socket) { g_signal_emit (manager, manager_signals[MESSAGE_SENT], 0, socket, msg->str, msg->id, msg->timeout); } manager->messages = g_list_remove_link (manager->messages, p); pending_message_free (msg); } return; } } } static void egg_tray_manager_handle_begin_message (EggTrayManager *manager, XClientMessageEvent *xevent) { GList *p; PendingMessage *msg; /* Check if the same message is * already in the queue and remove it if so */ for (p = manager->messages; p; p = p->next) { PendingMessage *msg = p->data; if (xevent->window == msg->window && xevent->data.l[4] == msg->id) { /* Hmm, we found it, now remove it */ pending_message_free (msg); manager->messages = g_list_remove_link (manager->messages, p); break; } } /* Now add the new message to the queue */ msg = g_new0 (PendingMessage, 1); msg->window = xevent->window; msg->timeout = xevent->data.l[2]; msg->len = xevent->data.l[3]; msg->id = xevent->data.l[4]; msg->remaining_len = msg->len; msg->str = g_malloc (msg->len + 1); msg->str[msg->len] = '\0'; manager->messages = g_list_prepend (manager->messages, msg); } static void egg_tray_manager_handle_cancel_message (EggTrayManager *manager, XClientMessageEvent *xevent) { GtkSocket *socket; socket = g_hash_table_lookup (manager->socket_table, GINT_TO_POINTER (xevent->window)); if (socket) { g_signal_emit (manager, manager_signals[MESSAGE_CANCELLED], 0, socket, xevent->data.l[2]); } } static GdkFilterReturn egg_tray_manager_handle_event (EggTrayManager *manager, XClientMessageEvent *xevent) { switch (xevent->data.l[1]) { case SYSTEM_TRAY_REQUEST_DOCK: egg_tray_manager_handle_dock_request (manager, xevent); return GDK_FILTER_REMOVE; case SYSTEM_TRAY_BEGIN_MESSAGE: egg_tray_manager_handle_begin_message (manager, xevent); return GDK_FILTER_REMOVE; case SYSTEM_TRAY_CANCEL_MESSAGE: egg_tray_manager_handle_cancel_message (manager, xevent); return GDK_FILTER_REMOVE; default: break; } return GDK_FILTER_CONTINUE; } static GdkFilterReturn egg_tray_manager_window_filter (GdkXEvent *xev, GdkEvent *event, gpointer data) { XEvent *xevent = (GdkXEvent *)xev; EggTrayManager *manager = data; if (xevent->type == ClientMessage) { if (xevent->xclient.message_type == manager->opcode_atom) { return egg_tray_manager_handle_event (manager, (XClientMessageEvent *)xevent); } else if (xevent->xclient.message_type == manager->message_data_atom) { egg_tray_manager_handle_message_data (manager, (XClientMessageEvent *)xevent); return GDK_FILTER_REMOVE; } } else if (xevent->type == SelectionClear) { g_signal_emit (manager, manager_signals[LOST_SELECTION], 0); egg_tray_manager_unmanage (manager); } return GDK_FILTER_CONTINUE; } static void egg_tray_manager_unmanage (EggTrayManager *manager) { Display *display; guint32 timestamp; GtkWidget *invisible; if (manager->invisible == NULL) return; invisible = manager->invisible; g_assert (GTK_IS_INVISIBLE (invisible)); g_assert (GTK_WIDGET_REALIZED (invisible)); g_assert (GDK_IS_WINDOW (invisible->window)); display = GDK_WINDOW_XDISPLAY (invisible->window); if (XGetSelectionOwner (display, manager->selection_atom) == GDK_WINDOW_XWINDOW (invisible->window)) { timestamp = gdk_x11_get_server_time (invisible->window); XSetSelectionOwner (display, manager->selection_atom, None, timestamp); } gdk_window_remove_filter (invisible->window, egg_tray_manager_window_filter, manager); manager->invisible = NULL; /* prior to destroy for reentrancy paranoia */ gtk_widget_destroy (invisible); g_object_unref (G_OBJECT (invisible)); } static gboolean egg_tray_manager_manage_xscreen (EggTrayManager *manager, Screen *xscreen) { GtkWidget *invisible; char *selection_atom_name; guint32 timestamp; GdkScreen *screen; g_return_val_if_fail (EGG_IS_TRAY_MANAGER (manager), FALSE); g_return_val_if_fail (manager->screen == NULL, FALSE); /* If there's already a manager running on the screen * we can't create another one. */ #if 0 if (egg_tray_manager_check_running_xscreen (xscreen)) return FALSE; #endif screen = gdk_display_get_screen (gdk_x11_lookup_xdisplay (DisplayOfScreen (xscreen)), XScreenNumberOfScreen (xscreen)); invisible = gtk_invisible_new_for_screen (screen); gtk_widget_realize (invisible); gtk_widget_add_events (invisible, GDK_PROPERTY_CHANGE_MASK | GDK_STRUCTURE_MASK); selection_atom_name = g_strdup_printf ("_NET_SYSTEM_TRAY_S%d", XScreenNumberOfScreen (xscreen)); manager->selection_atom = XInternAtom (DisplayOfScreen (xscreen), selection_atom_name, False); g_free (selection_atom_name); timestamp = gdk_x11_get_server_time (invisible->window); XSetSelectionOwner (DisplayOfScreen (xscreen), manager->selection_atom, GDK_WINDOW_XWINDOW (invisible->window), timestamp); /* Check if we were could set the selection owner successfully */ if (XGetSelectionOwner (DisplayOfScreen (xscreen), manager->selection_atom) == GDK_WINDOW_XWINDOW (invisible->window)) { XClientMessageEvent xev; xev.type = ClientMessage; xev.window = RootWindowOfScreen (xscreen); xev.message_type = XInternAtom (DisplayOfScreen (xscreen), "MANAGER", False); xev.format = 32; xev.data.l[0] = timestamp; xev.data.l[1] = manager->selection_atom; xev.data.l[2] = GDK_WINDOW_XWINDOW (invisible->window); xev.data.l[3] = 0; /* manager specific data */ xev.data.l[4] = 0; /* manager specific data */ XSendEvent (DisplayOfScreen (xscreen), RootWindowOfScreen (xscreen), False, StructureNotifyMask, (XEvent *)&xev); manager->invisible = invisible; g_object_ref (G_OBJECT (manager->invisible)); manager->opcode_atom = XInternAtom (DisplayOfScreen (xscreen), "_NET_SYSTEM_TRAY_OPCODE", False); manager->message_data_atom = XInternAtom (DisplayOfScreen (xscreen), "_NET_SYSTEM_TRAY_MESSAGE_DATA", False); /* Add a window filter */ gdk_window_add_filter (invisible->window, egg_tray_manager_window_filter, manager); return TRUE; } else { gtk_widget_destroy (invisible); return FALSE; } } gboolean egg_tray_manager_manage_screen (EggTrayManager *manager, GdkScreen *screen) { g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE); g_return_val_if_fail (manager->screen == NULL, FALSE); return egg_tray_manager_manage_xscreen (manager, GDK_SCREEN_XSCREEN (screen)); } static gboolean egg_tray_manager_check_running_xscreen (Screen *xscreen) { Atom selection_atom; char *selection_atom_name; selection_atom_name = g_strdup_printf ("_NET_SYSTEM_TRAY_S%d", XScreenNumberOfScreen (xscreen)); selection_atom = XInternAtom (DisplayOfScreen (xscreen), selection_atom_name, False); g_free (selection_atom_name); if (XGetSelectionOwner (DisplayOfScreen (xscreen), selection_atom)) return TRUE; else return FALSE; } gboolean egg_tray_manager_check_running (GdkScreen *screen) { g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE); return egg_tray_manager_check_running_xscreen (GDK_SCREEN_XSCREEN (screen)); } char * egg_tray_manager_get_child_title (EggTrayManager *manager, EggTrayManagerChild *child) { Window *child_window; Atom utf8_string, atom, type; int result; char *retval; int format; gulong nitems; gulong bytes_after; guchar *val; g_return_val_if_fail (EGG_IS_TRAY_MANAGER (manager), NULL); g_return_val_if_fail (GTK_IS_SOCKET (child), NULL); child_window = g_object_get_data (G_OBJECT (child), "egg-tray-child-window"); utf8_string = XInternAtom (gdk_helper_display(), "UTF8_STRING", False); atom = XInternAtom (gdk_helper_display(), "_NET_WM_NAME", False); gdk_error_trap_push (); result = XGetWindowProperty (gdk_helper_display(), *child_window, atom, 0, G_MAXLONG, False, utf8_string, &type, &format, &nitems, &bytes_after, (guchar **)&val); if (gdk_error_trap_pop () || result != Success) return NULL; if (type != utf8_string || format != 8 || nitems == 0) { if (val) XFree (val); return NULL; } if (!g_utf8_validate ((const gchar*) val, nitems, NULL)) { XFree (val); return NULL; } retval = g_strndup ((const gchar*) val, nitems); XFree (val); return retval; } trayer-srg-trayer-1.1.7/eggtraymanager.h000066400000000000000000000061451307264730600203070ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* eggtraymanager.h * Copyright (C) 2002 Anders Carlsson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef __EGG_TRAY_MANAGER_H__ #define __EGG_TRAY_MANAGER_H__ #include #include G_BEGIN_DECLS #define EGG_TYPE_TRAY_MANAGER (egg_tray_manager_get_type ()) #define EGG_TRAY_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_TRAY_MANAGER, EggTrayManager)) #define EGG_TRAY_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_TRAY_MANAGER, EggTrayManagerClass)) #define EGG_IS_TRAY_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_TRAY_MANAGER)) #define EGG_IS_TRAY_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_TRAY_MANAGER)) #define EGG_TRAY_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_TRAY_MANAGER, EggTrayManagerClass)) typedef struct _EggTrayManager EggTrayManager; typedef struct _EggTrayManagerClass EggTrayManagerClass; typedef struct _EggTrayManagerChild EggTrayManagerChild; struct _EggTrayManager { GObject parent_instance; Atom opcode_atom; Atom selection_atom; Atom message_data_atom; GtkWidget *invisible; GdkScreen *screen; GList *messages; GHashTable *socket_table; }; struct _EggTrayManagerClass { GObjectClass parent_class; void (* tray_icon_added) (EggTrayManager *manager, EggTrayManagerChild *child); void (* tray_icon_removed) (EggTrayManager *manager, EggTrayManagerChild *child); void (* message_sent) (EggTrayManager *manager, EggTrayManagerChild *child, const gchar *message, glong id, glong timeout); void (* message_cancelled) (EggTrayManager *manager, EggTrayManagerChild *child, glong id); void (* lost_selection) (EggTrayManager *manager); }; GType egg_tray_manager_get_type (void); gboolean egg_tray_manager_check_running (GdkScreen *screen); EggTrayManager *egg_tray_manager_new (void); gboolean egg_tray_manager_manage_screen (EggTrayManager *manager, GdkScreen *screen); char *egg_tray_manager_get_child_title (EggTrayManager *manager, EggTrayManagerChild *child); G_END_DECLS #endif /* __EGG_TRAY_MANAGER_H__ */ trayer-srg-trayer-1.1.7/fixedtip.c000066400000000000000000000100721307264730600171130ustar00rootroot00000000000000/* Metacity fixed tooltip routine */ /* * Copyright (C) 2001 Havoc Pennington * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include "fixedtip.h" static GtkWidget *tip = NULL; static GtkWidget *label = NULL; static int screen_width = 0; static int screen_height = 0; static gboolean button_press_handler (GtkWidget *tip, GdkEvent *event, void *data) { fixed_tip_hide (); return FALSE; } static gboolean expose_handler (GtkTooltips *tooltips) { gtk_paint_flat_box (tip->style, tip->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, tip, "tooltip", 0, 0, -1, -1); return FALSE; } void fixed_tip_show (int screen_number, int root_x, int root_y, gboolean strut_is_vertical, int strut, const char *markup_text) { int w, h; if (tip == NULL) { tip = gtk_window_new (GTK_WINDOW_POPUP); #ifdef HAVE_GTK_MULTIHEAD { GdkScreen *gdk_screen; gdk_screen = gdk_display_get_screen (gdk_get_default_display (), screen_number); gtk_window_set_screen (GTK_WINDOW (tip), gdk_screen); screen_width = gdk_screen_get_width (gdk_screen); screen_height = gdk_screen_get_height (gdk_screen); } #else screen_width = gdk_screen_width (); screen_height = gdk_screen_height (); #endif gtk_widget_set_app_paintable (tip, TRUE); //gtk_window_set_policy (GTK_WINDOW (tip), FALSE, FALSE, TRUE); gtk_window_set_resizable(GTK_WINDOW (tip), FALSE); gtk_widget_set_name (tip, "gtk-tooltips"); gtk_container_set_border_width (GTK_CONTAINER (tip), 4); g_signal_connect (G_OBJECT (tip), "expose_event", G_CALLBACK (expose_handler), NULL); gtk_widget_add_events (tip, GDK_BUTTON_PRESS_MASK); g_signal_connect (G_OBJECT (tip), "button_press_event", G_CALLBACK (button_press_handler), NULL); label = gtk_label_new (NULL); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); gtk_widget_show (label); gtk_container_add (GTK_CONTAINER (tip), label); g_signal_connect (G_OBJECT (tip), "destroy", G_CALLBACK (gtk_widget_destroyed), &tip); } gtk_label_set_markup (GTK_LABEL (label), markup_text); /* FIXME should also handle Xinerama here, just to be * really cool */ gtk_window_get_size (GTK_WINDOW (tip), &w, &h); /* pad between panel and message window */ #define PAD 5 if (strut_is_vertical) { if (strut > root_x) root_x = strut + PAD; else root_x = strut - w - PAD; root_y -= h / 2; } else { if (strut > root_y) root_y = strut + PAD; else root_y = strut - h - PAD; root_x -= w / 2; } /* Push onscreen */ if ((root_x + w) > screen_width) root_x -= (root_x + w) - screen_width; if ((root_y + h) > screen_height) root_y -= (root_y + h) - screen_height; gtk_window_move (GTK_WINDOW (tip), root_x, root_y); gtk_widget_show (tip); } void fixed_tip_hide (void) { if (tip) { gtk_widget_destroy (tip); tip = NULL; } } trayer-srg-trayer-1.1.7/fixedtip.h000066400000000000000000000024071307264730600171230ustar00rootroot00000000000000/* Fixed tooltip routine */ /* * Copyright (C) 2001 Havoc Pennington, 2002 Red Hat Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #ifndef FIXED_TIP_H #define FIXED_TIP_H #include #include /* root_x, root_y are where the speech balloon should be * "pointing" and the strut is the panel edge we should be * alongside. */ void fixed_tip_show (int screen_number, int root_x, int root_y, gboolean strut_is_vertical, int strut, const char *markup_text); void fixed_tip_hide (void); #endif trayer-srg-trayer-1.1.7/gdk-helper.c000066400000000000000000000003061307264730600173200ustar00rootroot00000000000000#include #include "gdk-helper.h" Display* gdk_helper_display() { return gdk_x11_display_get_xdisplay(gdk_display_get_default()); } trayer-srg-trayer-1.1.7/gdk-helper.h000066400000000000000000000001131307264730600173210ustar00rootroot00000000000000#include #include Display* gdk_helper_display(); trayer-srg-trayer-1.1.7/main.c000066400000000000000000000052011307264730600162210ustar00rootroot00000000000000#include #include #include #include #include "panel.h" #include "misc.h" #include "eggtraymanager.h" #include "fixedtip.h" #include "main.h" //#define DEBUG #include "dbg.h" typedef struct { GtkWidget *mainw; panel *panel; GtkWidget *box; ///// EggTrayManager *tray_manager; } tray; static void tray_added (EggTrayManager *manager, GtkWidget *icon, void *data) { GtkWidget *box = (GtkWidget *)data; gtk_box_pack_end (GTK_BOX (box), icon, FALSE, FALSE, 0); gtk_widget_show (icon); } static void tray_removed (EggTrayManager *manager, GtkWidget *icon, void *data) { } static void message_sent (EggTrayManager *manager, GtkWidget *icon, const char *text, glong id, glong timeout, void *data) { /* FIXME multihead */ int x, y; gdk_window_get_origin (icon->window, &x, &y); fixed_tip_show (0, x, y, FALSE, gdk_screen_height () - 50, text); } static void message_cancelled (EggTrayManager *manager, GtkWidget *icon, glong id, void *data) { } void tray_destructor(panel *p) { tray *tr = (tray *)p->priv; ENTER; /* Make sure we drop the manager selection */ g_object_unref (G_OBJECT (tr->tray_manager)); fixed_tip_hide (); gtk_widget_destroy(tr->mainw); g_free(tr); RET(); } int tray_constructor(panel *p) { tray *tr; GdkScreen *screen; ENTER; tr = g_new0(tray, 1); g_return_val_if_fail(tr != NULL, 0); p->priv = tr; tr->panel = p; tr->mainw = gtk_alignment_new (0.5, 0.5, 1.0, 1.0); tr->box = p->my_box_new(FALSE, 1); gtk_box_set_spacing(GTK_BOX(tr->box), p->icon_spacing); gtk_container_add (GTK_CONTAINER (tr->mainw), tr->box); gtk_container_add(GTK_CONTAINER(p->box), tr->mainw); screen = gtk_widget_get_screen (GTK_WIDGET (p->topgwin)); if (egg_tray_manager_check_running(screen)) { ERR("another systray already running\n"); RET(1); } tr->tray_manager = egg_tray_manager_new (); if (!egg_tray_manager_manage_screen (tr->tray_manager, screen)) g_printerr ("System tray didn't get the system tray manager selection\n"); g_signal_connect (tr->tray_manager, "tray_icon_added", G_CALLBACK (tray_added), tr->box); g_signal_connect (tr->tray_manager, "tray_icon_removed", G_CALLBACK (tray_removed), tr->box); g_signal_connect (tr->tray_manager, "message_sent", G_CALLBACK (message_sent), tr->box); g_signal_connect (tr->tray_manager, "message_cancelled", G_CALLBACK (message_cancelled), tr->box); RET(1); } trayer-srg-trayer-1.1.7/main.h000066400000000000000000000001251307264730600162260ustar00rootroot00000000000000#include "panel.h" int tray_constructor(panel *p); void tray_destructor(panel *p); trayer-srg-trayer-1.1.7/man/000077500000000000000000000000001307264730600157065ustar00rootroot00000000000000trayer-srg-trayer-1.1.7/man/trayer.1000066400000000000000000000117251307264730600173040ustar00rootroot00000000000000.TH TRAYER-SRG 1 LOCAL .SH NAME trayer-srg - a lightweight GTK2-based systray for UNIX desktop .SH SYNOPSYS .B trayer .B "[ .I OPTIONS .B "] .SH DESCRIPTION trayer is small program designed to provide systray functionality present in GNOME/KDE desktop enviroments for window managers which doesn't support that function. It's similar to other applications such as 'peksystray' and 'docker'. trayer code was extracted from fbpanel application, you can find more about it on it's homepage: .IB http://fbpanel.sourceforge.net/ You can find new versions of trayer and support on FVWM-Crystal project homepage: .IB http://fvwm-crystal.berlios.de/ trayer-srg was forked from trayer in january 2010 to add some fancy features and clean up code. It contains all changes from above versions as far as known. Code of trayer-srg can be found on github: .IB http://github.com/sargon/trayer-srg .SH OPTIONS .TP .BR \-h prints help message and exits .TP .BR \-v prints version and exits .TP .BR \--edge " EDGE" Use .I EDGE for orientation. Possible values for .I EDGE are .BR left, .BR right, .BR top, .BR bottom or .BR none. The default value is .BR bottom. .TP .BR \--align " ALIGNMENT" Orientation of docked icons inside the trayer panel. Possible values are .BR left, .BR center, .BR right, or .BR none. The default value is .BR center. .TP .BR \--margin " NUM" Length of margin in pixels. The default value is .BR 0. .TP .BR \--distance " NUM" Space between trayer's window and screen edge. When set to 0 the option has no effect. The default value is .BR 0. .TP .BR \--distancefrom " EDGE" Specifies which edge to calculate distance from, see .BR --edge. The default value is .BR top. When .BR --distance is 0 then this option has no effect. .TP .BR \--widthtype " TYPE" Determine how width is calculated. Possible values for .I TYPE are .BR pixel, .BR percent, .BR request or .BR none. The default value is .BR percent. .TP .BR \--width " NUM" Width of a panel. When .BR --widthtype=request this option has no effect. The default value is .BR 100. .TP .BR \--heighttype " TYPE" Determine how height is calculated. Possible values for .I TYPE are .BR pixel, .BR request or .BR none. The default value is .BR pixel. .TP .BR \--height " NUM" Height of a panel. When .BR --heigthtype=request this option has no effect. The default value is .BR 26. .TP .BR \--SetDockTpe " BOOL" Identify panel window type as dock. The default value is .BR true. .TP .BR \--SetPartialStrut " BOOL" Reserve panel's space so that it will not be covered by maximazied windows. The default value is .BR false. .TP .BR \--transparent " BOOL" Use transparency. Default value is .BR false. .TP .BR \--tint " NUM" Color used to "tint" background wallpaper with. .I NUM is 32bit width hexadecimal number. The default value is .BR 0xFFFFFFFF. .TP .BR \--alpha " NUM" Percentage of transparency. .I NUM should be a value between 0 and 256. The default value is .BR 127. .TP .BR \--expand " BOOL" Specifies if trayer can accomodate extra space or not . The default value is .BR true. .TP .BR \--padding " NUM" Number of extra pixel space between trayer's window frame and docked icons. The default value is .BR 0. .TP .BR \--monitor " NUM|STRING" Define the monitor on which you like trayer to appear, number of zero to number of monitors minus one, or the string "primary" are valid. The default value is .BR 0. .SH EXAMPLES .LP Place trayer to the top right edge of the screen and prevent other fullsize windows to overlay it: .RS .nf \f8trayer trayer --edge top --align right --SetDockType true --SetPartialStrut true --expand true --transparent true\fP .fi .RE .SH BUGS Report bugs to the issue tracker: .I https://github.com/sargon/trayer-srg/issues .SH CONTRIBUTORS Following people are or has been involved in development of trayer-srg: .IP "Maciej Delmanowski " .IP "Anatoly Asviyan fbpanel .IP "Rafal Bisingier " conversion of configuration using ~/.fbpanel/* files to commandline options .IP "Grzegorz Niewêg³owski " code extraction from fbpanel .IP "Thomas Rydzynski" added new option 'distance' .IP "Keegan Carruthers-Smith " fix align .IP "Yury Akudovich" added new option distancefrom option .IP "Jens Peter Secher " various (debian trayer fork) .IP "Daniel Ehlers " multi monitor support, code cleanup and current maintainer. .IP "Stu Black" help closing a problem with wrong values in _NET_WM_STRUT_PARTIAL .IP "Michael Weber" fix build problems, improvements cmdline parameter handling .IP "Johannes Bittner" primary switch for monitor selection .IP "Vladimir Murzin " fixing transparency startup problem .IP "Corey Richardson " Found some default value fuckup .IP "Constantine Verutin" React on changes in monitor setup. .IP "Robbie Harwood" Fixup build .IP "Omar Sandoval" Fixups .SH AUTHOR This man page is written by Daniel Ehlers. trayer-srg-trayer-1.1.7/misc.c000066400000000000000000000470141307264730600162400ustar00rootroot00000000000000 #include #include #include #include #include #include #include #include #include #include "misc.h" #include "panel.h" #include "gdk-helper.h" //#define DEBUG #include "dbg.h" /* X11 data types */ Atom a_UTF8_STRING; Atom a_XROOTPMAP_ID; /* old WM spec */ Atom a_WM_STATE; Atom a_WM_CLASS; /* new NET spec */ Atom a_NET_WORKAREA; Atom a_NET_CLIENT_LIST; Atom a_NET_CLIENT_LIST_STACKING; Atom a_NET_NUMBER_OF_DESKTOPS; Atom a_NET_CURRENT_DESKTOP; Atom a_NET_DESKTOP_NAMES; Atom a_NET_ACTIVE_WINDOW; Atom a_NET_WM_DESKTOP; Atom a_NET_WM_STATE; Atom a_NET_WM_STATE_SKIP_TASKBAR; Atom a_NET_WM_STATE_SKIP_PAGER; Atom a_NET_WM_STATE_STICKY; Atom a_NET_WM_STATE_HIDDEN; Atom a_NET_WM_STATE_SHADED; Atom a_NET_WM_WINDOW_TYPE; Atom a_NET_WM_WINDOW_TYPE_DESKTOP; Atom a_NET_WM_WINDOW_TYPE_DOCK; Atom a_NET_WM_WINDOW_TYPE_TOOLBAR; Atom a_NET_WM_WINDOW_TYPE_MENU; Atom a_NET_WM_WINDOW_TYPE_UTILITY; Atom a_NET_WM_WINDOW_TYPE_SPLASH; Atom a_NET_WM_WINDOW_TYPE_DIALOG; Atom a_NET_WM_WINDOW_TYPE_NORMAL; Atom a_NET_WM_DESKTOP; Atom a_NET_WM_NAME; Atom a_NET_WM_STRUT; Atom a_NET_WM_STRUT_PARTIAL; Atom a_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR; pair allign_pair[] = { { ALLIGN_NONE, "none" }, { ALLIGN_LEFT, "left" }, { ALLIGN_RIGHT, "right" }, { ALLIGN_CENTER, "center"}, { 0, NULL }, }; pair edge_pair[] = { { EDGE_NONE, "none" }, { EDGE_LEFT, "left" }, { EDGE_RIGHT, "right" }, { EDGE_TOP, "top" }, { EDGE_BOTTOM, "bottom" }, { 0, NULL }, }; pair distancefrom_pair[] = { { DISTANCEFROM_NONE, "none" }, { DISTANCEFROM_LEFT, "left" }, { DISTANCEFROM_RIGHT, "right" }, { DISTANCEFROM_TOP, "top" }, { DISTANCEFROM_BOTTOM, "bottom" }, { 0, NULL }, }; pair width_pair[] = { { WIDTH_NONE, "none" }, { WIDTH_REQUEST, "request" }, { WIDTH_PIXEL, "pixel" }, { WIDTH_PERCENT, "percent" }, { 0, NULL }, }; pair height_pair[] = { { HEIGHT_NONE, "none" }, { HEIGHT_REQUEST, "request" }, { HEIGHT_PIXEL, "pixel" }, { 0, NULL }, }; pair bool_pair[] = { { 0, "false" }, { 1, "true" }, { 0, NULL }, }; pair pos_pair[] = { { POS_NONE, "none" }, { POS_START, "start" }, { POS_END, "end" }, { 0, NULL}, }; int str2num(pair *p, gchar *str, int defval) { ENTER; for (;p && p->str; p++) { if (!g_ascii_strcasecmp(str, p->str)) RET(p->num); } RET(defval); } gchar * num2str(pair *p, int num, gchar *defval) { ENTER; for (;p && p->str; p++) { if (num == p->num) RET(p->str); } RET(defval); } int get_line(FILE *fp, line *s) { gchar *tmp, *tmp2; ENTER; if (!fp) { s->type = LINE_NONE; RET(s->type); } s->type = LINE_NONE; while (fgets(s->str, s->len, fp)) { g_strstrip(s->str); if (s->str[0] == '#' || s->str[0] == 0) { continue; } DBG( ">> %s\n", s->str); if (!g_ascii_strcasecmp(s->str, "}")) { s->type = LINE_BLOCK_END; break; } s->t[0] = s->str; for (tmp = s->str; isalnum(*tmp); tmp++); for (tmp2 = tmp; isspace(*tmp2); tmp2++); if (*tmp2 == '=') { for (++tmp2; isspace(*tmp2); tmp2++); s->t[1] = tmp2; *tmp = 0; s->type = LINE_VAR; } else if (*tmp2 == '{') { *tmp = 0; s->type = LINE_BLOCK_START; } else { ERR( "parser: unknown token: '%c'\n", *tmp2); } break; } RET(s->type); } int get_line_as_is(FILE *fp, line *s) { gchar *tmp, *tmp2; ENTER; if (!fp) { s->type = LINE_NONE; RET(s->type); } s->type = LINE_NONE; while (fgets(s->str, s->len, fp)) { g_strstrip(s->str); if (s->str[0] == '#' || s->str[0] == 0) continue; DBG( ">> %s\n", s->str); if (!g_ascii_strcasecmp(s->str, "}")) { s->type = LINE_BLOCK_END; DBG( " : line_block_end\n"); break; } for (tmp = s->str; isalnum(*tmp); tmp++); for (tmp2 = tmp; isspace(*tmp2); tmp2++); if (*tmp2 == '=') { s->type = LINE_VAR; } else if (*tmp2 == '{') { s->type = LINE_BLOCK_START; } else { DBG( " : ? <%c>\n", *tmp2); } break; } RET(s->type); } void resolve_atoms() { ENTER; a_UTF8_STRING = XInternAtom(gdk_helper_display(), "UTF8_STRING", False); a_XROOTPMAP_ID = XInternAtom(gdk_helper_display(), "_XROOTPMAP_ID", False); a_WM_STATE = XInternAtom(gdk_helper_display(), "WM_STATE", False); a_WM_CLASS = XInternAtom(gdk_helper_display(), "WM_CLASS", False); a_NET_WORKAREA = XInternAtom(gdk_helper_display(), "_NET_WORKAREA", False); a_NET_CLIENT_LIST = XInternAtom(gdk_helper_display(), "_NET_CLIENT_LIST", False); a_NET_CLIENT_LIST_STACKING = XInternAtom(gdk_helper_display(), "_NET_CLIENT_LIST_STACKING", False); a_NET_NUMBER_OF_DESKTOPS = XInternAtom(gdk_helper_display(), "_NET_NUMBER_OF_DESKTOPS", False); a_NET_CURRENT_DESKTOP = XInternAtom(gdk_helper_display(), "_NET_CURRENT_DESKTOP", False); a_NET_DESKTOP_NAMES = XInternAtom(gdk_helper_display(), "_NET_DESKTOP_NAMES", False); a_NET_ACTIVE_WINDOW = XInternAtom(gdk_helper_display(), "_NET_ACTIVE_WINDOW", False); a_NET_WM_DESKTOP = XInternAtom(gdk_helper_display(), "_NET_WM_DESKTOP", False); a_NET_WM_STATE = XInternAtom(gdk_helper_display(), "_NET_WM_STATE", False); a_NET_WM_STATE_SKIP_TASKBAR = XInternAtom(gdk_helper_display(), "_NET_WM_STATE_SKIP_TASKBAR", False); a_NET_WM_STATE_SKIP_PAGER = XInternAtom(gdk_helper_display(), "_NET_WM_STATE_SKIP_PAGER", False); a_NET_WM_STATE_STICKY = XInternAtom(gdk_helper_display(), "_NET_WM_STATE_STICKY", False); a_NET_WM_STATE_HIDDEN = XInternAtom(gdk_helper_display(), "_NET_WM_STATE_HIDDEN", False); a_NET_WM_STATE_SHADED = XInternAtom(gdk_helper_display(), "_NET_WM_STATE_SHADED", False); a_NET_WM_WINDOW_TYPE = XInternAtom(gdk_helper_display(), "_NET_WM_WINDOW_TYPE", False); a_NET_WM_WINDOW_TYPE_DESKTOP = XInternAtom(gdk_helper_display(), "_NET_WM_WINDOW_TYPE_DESKTOP", False); a_NET_WM_WINDOW_TYPE_DOCK = XInternAtom(gdk_helper_display(), "_NET_WM_WINDOW_TYPE_DOCK", False); a_NET_WM_WINDOW_TYPE_TOOLBAR = XInternAtom(gdk_helper_display(), "_NET_WM_WINDOW_TYPE_TOOLBAR", False); a_NET_WM_WINDOW_TYPE_MENU = XInternAtom(gdk_helper_display(), "_NET_WM_WINDOW_TYPE_MENU", False); a_NET_WM_WINDOW_TYPE_UTILITY = XInternAtom(gdk_helper_display(), "_NET_WM_WINDOW_TYPE_UTILITY", False); a_NET_WM_WINDOW_TYPE_SPLASH = XInternAtom(gdk_helper_display(), "_NET_WM_WINDOW_TYPE_SPLASH", False); a_NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(gdk_helper_display(), "_NET_WM_WINDOW_TYPE_DIALOG", False); a_NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(gdk_helper_display(), "_NET_WM_WINDOW_TYPE_NORMAL", False); a_NET_WM_DESKTOP = XInternAtom(gdk_helper_display(), "_NET_WM_DESKTOP", False); a_NET_WM_NAME = XInternAtom(gdk_helper_display(), "_NET_WM_NAME", False); a_NET_WM_STRUT = XInternAtom(gdk_helper_display(), "_NET_WM_STRUT", False); a_NET_WM_STRUT_PARTIAL = XInternAtom(gdk_helper_display(), "_NET_WM_STRUT_PARTIAL", False); a_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR = XInternAtom(gdk_helper_display(), "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False); RET(); } void Xclimsg(Window win, long type, long l0, long l1, long l2, long l3, long l4) { XClientMessageEvent xev; xev.type = ClientMessage; xev.window = win; xev.message_type = type; xev.format = 32; xev.data.l[0] = l0; xev.data.l[1] = l1; xev.data.l[2] = l2; xev.data.l[3] = l3; xev.data.l[4] = l4; XSendEvent(gdk_helper_display(), GDK_ROOT_WINDOW(), False, (SubstructureNotifyMask | SubstructureRedirectMask), (XEvent *) & xev); } void * get_xaproperty (Window win, Atom prop, Atom type, int *nitems) { Atom type_ret; int format_ret; unsigned long items_ret; unsigned long after_ret; unsigned char *prop_data; ENTER; prop_data = NULL; XGetWindowProperty (gdk_helper_display(), win, prop, 0, 0x7fffffff, False, type, &type_ret, &format_ret, &items_ret, &after_ret, &prop_data); if (nitems) *nitems = items_ret; RET(prop_data); } static char* text_property_to_utf8 (const XTextProperty *prop) { char **list; int count; char *retval; ENTER; list = NULL; count = gdk_text_property_to_utf8_list (gdk_x11_xatom_to_atom (prop->encoding), prop->format, prop->value, prop->nitems, &list); DBG("count=%d\n", count); if (count == 0) return NULL; retval = list[0]; list[0] = g_strdup (""); /* something to free */ g_strfreev (list); RET(retval); } char * get_textproperty(Window win, Atom atom) { XTextProperty text_prop; char *retval; ENTER; if (XGetTextProperty(gdk_helper_display(), win, &text_prop, atom)) { DBG("format=%d enc=%d nitems=%d value=%s \n", text_prop.format, text_prop.encoding, text_prop.nitems, text_prop.value); retval = text_property_to_utf8 (&text_prop); if (text_prop.nitems > 0) XFree (text_prop.value); RET(retval); } RET(NULL); } int get_net_number_of_desktops() { int desknum; unsigned long *data; ENTER; data = get_xaproperty (GDK_ROOT_WINDOW(), a_NET_NUMBER_OF_DESKTOPS, XA_CARDINAL, 0); if (!data) RET(0); desknum = *data; XFree (data); RET(desknum); } int get_net_current_desktop () { int desk; unsigned long *data; ENTER; data = get_xaproperty (GDK_ROOT_WINDOW(), a_NET_CURRENT_DESKTOP, XA_CARDINAL, 0); if (!data) RET(0); desk = *data; XFree (data); RET(desk); } int get_net_wm_desktop(Window win) { int desk = 0; unsigned long *data; ENTER; data = get_xaproperty (win, a_NET_WM_DESKTOP, XA_CARDINAL, 0); if (data) { desk = *data; XFree (data); } RET(desk); } void get_net_wm_state(Window win, net_wm_state *nws) { Atom *state; int num3; ENTER; memset(nws, 0, sizeof(*nws)); if (!(state = get_xaproperty(win, a_NET_WM_STATE, XA_ATOM, &num3))) RET(); DBG( "%x: netwm state = { ", (unsigned int)win); while (--num3 >= 0) { if (state[num3] == a_NET_WM_STATE_SKIP_PAGER) { DBG("NET_WM_STATE_SKIP_PAGER "); nws->skip_pager = 1; } else if (state[num3] == a_NET_WM_STATE_SKIP_TASKBAR) { DBG( "NET_WM_STATE_SKIP_TASKBAR "); nws->skip_taskbar = 1; } else if (state[num3] == a_NET_WM_STATE_STICKY) { DBG( "NET_WM_STATE_STICKY "); nws->sticky = 1; } else if (state[num3] == a_NET_WM_STATE_HIDDEN) { DBG( "NET_WM_STATE_HIDDEN "); nws->hidden = 1; } else if (state[num3] == a_NET_WM_STATE_SHADED) { DBG( "NET_WM_STATE_SHADED "); nws->shaded = 1; } else { DBG( "... "); } } XFree(state); DBG( "}\n"); RET(); } void get_net_wm_window_type(Window win, net_wm_window_type *nwwt) { Atom *state; int num3; ENTER; memset(nwwt, 0, sizeof(*nwwt)); if (!(state = get_xaproperty(win, a_NET_WM_WINDOW_TYPE, XA_ATOM, &num3))) RET(); DBG( "%x: netwm state = { ", (unsigned int)win); while (--num3 >= 0) { if (state[num3] == a_NET_WM_WINDOW_TYPE_DESKTOP) { DBG("NET_WM_WINDOW_TYPE_DESKTOP "); nwwt->desktop = 1; } else if (state[num3] == a_NET_WM_WINDOW_TYPE_DOCK) { DBG( "NET_WM_WINDOW_TYPE_DOCK "); nwwt->dock = 1; } else if (state[num3] == a_NET_WM_WINDOW_TYPE_TOOLBAR) { DBG( "NET_WM_WINDOW_TYPE_TOOLBAR "); nwwt->toolbar = 1; } else if (state[num3] == a_NET_WM_WINDOW_TYPE_MENU) { DBG( "NET_WM_WINDOW_TYPE_MENU "); nwwt->menu = 1; } else if (state[num3] == a_NET_WM_WINDOW_TYPE_UTILITY) { DBG( "NET_WM_WINDOW_TYPE_UTILITY "); nwwt->utility = 1; } else if (state[num3] == a_NET_WM_WINDOW_TYPE_SPLASH) { DBG( "NET_WM_WINDOW_TYPE_SPLASH "); nwwt->splash = 1; } else if (state[num3] == a_NET_WM_WINDOW_TYPE_DIALOG) { DBG( "NET_WM_WINDOW_TYPE_DIALOG "); nwwt->dialog = 1; } else if (state[num3] == a_NET_WM_WINDOW_TYPE_NORMAL) { DBG( "NET_WM_WINDOW_TYPE_NORMAL "); nwwt->normal = 1; } else { DBG( "... "); } } XFree(state); DBG( "}\n"); RET(); } int get_wm_state (Window win) { unsigned long *data; int ret = 0; ENTER; data = get_xaproperty (win, a_WM_STATE, a_WM_STATE, 0); if (data) { ret = data[0]; XFree (data); } RET(ret); } static void calculate_width(int scrw, int wtype, int allign, int margin, int *panw, int *x) { ENTER; DBG("scrw=%d\n", scrw); DBG("IN panw=%d\n", *panw); //scrw -= 2; if (wtype == WIDTH_PERCENT) { /* sanity check */ if (*panw > 100) *panw = 100; else if (*panw < 0) *panw = 1; *panw = ((gfloat) scrw * (gfloat) *panw) / 100.0; } if (allign != ALLIGN_CENTER) { if (margin > scrw) { ERR( "margin is bigger then edge size %d > %d. Ignoring margin\n", margin, scrw); margin = 0; } if (wtype == WIDTH_PERCENT) //*panw = MAX(scrw - margin, *panw); ; else *panw = MIN(scrw - margin, *panw); } DBG("OUT panw=%d\n", *panw); if (allign == ALLIGN_LEFT) *x += margin; else if (allign == ALLIGN_RIGHT) { *x += scrw - *panw - margin; if (*x < 0) *x = 0; } else if (allign == ALLIGN_CENTER) *x += (scrw - *panw) / 2; RET(); } void calculate_position(panel *np, int distance,int distancefrom) { int sswidth, ssheight, minx, miny, distancex, distancey; GdkScreen *screen; GdkDisplay *display; GdkRectangle *monitorGeometry; ENTER; display = gdk_display_get_default (); screen = gdk_display_get_screen(display,0); monitorGeometry = (GdkRectangle*) malloc(sizeof(GdkRectangle)); if (np->monitor >= gdk_screen_get_n_monitors(screen)) { np->monitor = 0; ERR("trayer: monitor parameter isn't valid, reseting value to 0\n"); } gdk_screen_get_monitor_geometry(screen,np->monitor,monitorGeometry); sswidth = monitorGeometry->width; ssheight = monitorGeometry->height; minx = monitorGeometry->x; miny = monitorGeometry->y; free(monitorGeometry); if (distancefrom == DISTANCEFROM_TOP || distancefrom == DISTANCEFROM_BOTTOM) { distancex = 0; distancey = (distancefrom == DISTANCEFROM_TOP) ? distance : -distance; } else { distancex = (distancefrom == DISTANCEFROM_LEFT) ? distance : -distance; distancey = 0; } if (np->edge == EDGE_TOP || np->edge == EDGE_BOTTOM) { np->aw = np->width; np->ax = minx + distancex; calculate_width(sswidth, np->widthtype, np->allign, np->margin, &np->aw, &np->ax); np->ah = np->height; np->ah = MIN(PANEL_HEIGHT_MAX, np->ah); np->ah = MAX(PANEL_HEIGHT_MIN, np->ah); np->ay = miny + ((np->edge == EDGE_TOP) ? distancey : (ssheight - np->ah - distancey)); } else { np->ah = np->width; np->ay = miny + distancey; calculate_width(ssheight, np->widthtype, np->allign, np->margin, &np->ah, &np->ay); np->aw = np->height; np->aw = MIN(PANEL_HEIGHT_MAX, np->aw); np->aw = MAX(PANEL_HEIGHT_MIN, np->aw); np->ax = minx + ((np->edge == EDGE_LEFT) ? distancex : (sswidth - np->aw - distancex)); } DBG("%s - x=%d y=%d w=%d h=%d\n", __FUNCTION__, np->ax, np->ay, np->aw, np->ah); RET(); } gchar * expand_tilda(gchar *file) { ENTER; RET((file[0] == '~') ? g_strdup_printf("%s%s", getenv("HOME"), file+1) : g_strdup(file)); } Window Select_Window(Display *dpy) { int status; Cursor cursor; XEvent event; Window target_win = None, root = RootWindow(dpy,DefaultScreen(dpy)); int buttons = 0; ENTER; /* Make the target cursor */ cursor = XCreateFontCursor(dpy, XC_crosshair); /* Grab the pointer using target cursor, letting it room all over */ status = XGrabPointer(dpy, root, False, ButtonPressMask|ButtonReleaseMask, GrabModeSync, GrabModeAsync, root, cursor, CurrentTime); if (status != GrabSuccess) { ERR("Can't grab the mouse."); RET(None); } /* Let the user select a window... */ while ((target_win == None) || (buttons != 0)) { /* allow one more event */ XAllowEvents(dpy, SyncPointer, CurrentTime); XWindowEvent(dpy, root, ButtonPressMask|ButtonReleaseMask, &event); switch (event.type) { case ButtonPress: if (target_win == None) { target_win = event.xbutton.subwindow; /* window selected */ DBG("target win = 0x%x\n", target_win); if (target_win == None) target_win = root; } buttons++; break; case ButtonRelease: if (buttons > 0) /* there may have been some down before we started */ buttons--; break; } } XUngrabPointer(dpy, CurrentTime); /* Done with pointer */ RET(target_win); } /* * SuxPanel version 0.1 * Copyright (c) 2003 Leandro Pereira * * This program may be distributed under the terms of GNU General * Public License version 2. You should have received a copy of the * license with this program; if not, please consult http://www.fsf.org/. * * This program comes with no warranty. Use at your own risk. * */ GtkWidget * gtk_image_new_from_file_scaled(const gchar *file, gint width, gint height) { GtkWidget *img; ENTER; if (g_file_test(file, G_FILE_TEST_EXISTS)) { GError *err = NULL; GdkPixbuf *pb; pb = gdk_pixbuf_new_from_file(file, &err); if (err || !pb) { g_error_free(err); } else { GdkPixbuf *pb_scaled; pb_scaled = gdk_pixbuf_scale_simple(pb, width, height, GDK_INTERP_BILINEAR); img = gtk_image_new_from_pixbuf(pb_scaled); g_object_unref(pb); g_object_unref(pb_scaled); RET(img); } } img = gtk_image_new_from_stock(GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_BUTTON); RET(img); } void get_button_spacing(GtkRequisition *req, GtkContainer *parent, gchar *name) { GtkWidget *b; //gint focus_width; //gint focus_pad; ENTER; b = gtk_button_new(); if (parent) gtk_container_add(parent, b); gtk_widget_set_name(GTK_WIDGET(b), name); GTK_WIDGET_UNSET_FLAGS (b, GTK_CAN_FOCUS); GTK_WIDGET_UNSET_FLAGS (b, GTK_CAN_DEFAULT); gtk_container_set_border_width (GTK_CONTAINER (b), 0); gtk_widget_show(b); gtk_widget_size_request(b, req); gtk_widget_destroy(b); RET(); } trayer-srg-trayer-1.1.7/misc.h000066400000000000000000000027471307264730600162510ustar00rootroot00000000000000#ifndef MISC_H #define MISC_H #include #include #include #include #include #include "panel.h" enum { LINE_NONE, LINE_BLOCK_START, LINE_BLOCK_END, LINE_VAR }; typedef struct { int num, len, type; gchar str[256]; gchar *t[3]; } line; typedef struct { int num; gchar *str; } pair; extern pair allign_pair[]; extern pair edge_pair[]; extern pair distancefrom_pair[]; extern pair width_pair[]; extern pair height_pair[]; extern pair bool_pair[]; extern pair pos_pair[]; int str2num(pair *p, gchar *str, int defval); gchar *num2str(pair *p, int num, gchar *defval); int get_line(FILE *fp, line *s); int get_line_as_is(FILE *fp, line *s); void Xclimsg(Window win, long type, long l0, long l1, long l2, long l3, long l4); void *get_xaproperty (Window win, Atom prop, Atom type, int *nitems); char *get_textproperty(Window win, Atom prop); void resolve_atoms(); Window Select_Window(Display *dpy); int get_net_number_of_desktops(); int get_net_current_desktop (); int get_net_wm_desktop(Window win); int get_wm_state (Window win); void get_net_wm_state(Window win, net_wm_state *nws); void get_net_wm_window_type(Window win, net_wm_window_type *nwwt); void calculate_position(panel *np, int distance,int distancefrom); gchar *expand_tilda(gchar *file); GtkWidget *gtk_image_new_from_file_scaled(const gchar *file, gint width, gint height); void get_button_spacing(GtkRequisition *req, GtkContainer *parent, gchar *name); #endif trayer-srg-trayer-1.1.7/panel.c000066400000000000000000000505531307264730600164060ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include "panel.h" #include "misc.h" #include "bg.h" #include "main.h" #include "gdk-helper.h" #define VERSION "1.1.6" static gchar version[] = VERSION; int distance=0, distancefrom=DISTANCEFROM_TOP; int expand=1 , padding=0; //#define DEBUG #include "dbg.h" static panel *p; static gchar *transparent_rc = "style 'transparent-style'\n" "{\n" "bg_pixmap[NORMAL] = \"\"\n" "bg_pixmap[INSENSITIVE] = \"\"\n" "bg_pixmap[PRELIGHT] = \"\"\n" "bg_pixmap[SELECTED] = \"\"\n" "bg_pixmap[ACTIVE] = \"\"\n" "}\n" "class \"GtkEventBox\" style \"transparent-style\"\n" "class \"GtkSocket\" style \"transparent-style\"\n" "class \"GtkBar\" style \"transparent-style\"\n" "class \"GtkBox\" style \"transparent-style\"\n" "\n"; static void set_bg(GtkWidget *widget, panel *p); /**************************************************** * panel's handlers for WM events * ****************************************************/ /* static void panel_del_wm_strut(panel *p) { XDeleteProperty(gdk_helper_display(), p->topxwin, a_NET_WM_STRUT); XDeleteProperty(gdk_helper_display(), p->topxwin, a_NET_WM_STRUT_PARTIAL); } */ static void panel_set_wm_strut(panel *p) { unsigned long data[12] = {0,0,0,0,0,0,0,0,0,0,0,0}; int i = 4; ENTER; if (!GTK_WIDGET_MAPPED (p->topgwin)) return; switch (p->edge) { case EDGE_LEFT: i = 0; data[i] = p->aw; data[4 + i*2] = p->ay; data[5 + i*2] = p->ay + p->ah - 1; break; case EDGE_RIGHT: i = 1; data[i] = p->aw; data[4 + i*2] = p->ay; data[5 + i*2] = p->ay + p->ah - 1; break; case EDGE_TOP: i = 2; data[i] = p->ah; data[4 + i*2] = p->ax; data[5 + i*2] = p->ax + p->aw - 1; break; case EDGE_BOTTOM: i = 3; data[i] = p->ah; data[4 + i*2] = p->ax; data[5 + i*2] = p->ax + p->aw - 1 ; break; default: ERR("wrong edge %d. strut won't be set\n", p->edge); RET(); } DBG("type %d. width %d. from %d to %d\n", i, data[i], data[4 + i*2], data[5 + i*2]); XChangeProperty(gdk_helper_display(), p->topxwin, a_NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) data, 12); /* old spec, for wms that do not support STRUT_PARTIAL */ XChangeProperty(gdk_helper_display(), p->topxwin, a_NET_WM_STRUT, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) data, 4); RET(); } static GdkFilterReturn panel_wm_events(GdkXEvent *xevent, GdkEvent *event, panel *p) { Atom at; Window win; XEvent *ev = (XEvent *) xevent; ENTER; DBG("win = 0x%x\n", ev->xproperty.window); if ( ev->type != PropertyNotify ) RET(GDK_FILTER_CONTINUE); at = ev->xproperty.atom; win = ev->xproperty.window; if (win == GDK_ROOT_WINDOW()) { if (at == a_XROOTPMAP_ID) { bg_rootbg_changed(); set_bg(p->topgwin, p); gtk_widget_queue_draw(p->topgwin); DBG("a_XROOTPMAP_ID\n"); } } RET(GDK_FILTER_CONTINUE); } /**************************************************** * panel's handlers for GTK events * ****************************************************/ static gint panel_delete_event(GtkWidget * widget, GdkEvent * event, gpointer data) { ENTER; RET(FALSE); } static gint panel_destroy_event(GtkWidget * widget, GdkEvent * event, gpointer data) { ENTER; // TODO need to cleanup gtk_main_quit(); RET(FALSE); } static gint panel_size_req(GtkWidget *widget, GtkRequisition *req, panel *p) { ENTER; DBG("IN req=(%d, %d)\n", req->width, req->height); if (p->widthtype == WIDTH_REQUEST) p->width = (p->orientation == ORIENT_HORIZ) ? req->width : req->height; if (p->heighttype == HEIGHT_REQUEST) p->height = (p->orientation == ORIENT_HORIZ) ? req->height : req->width; calculate_position(p, distance,distancefrom); req->width = p->aw; req->height = p->ah; DBG("OUT req=(%d, %d)\n", req->width, req->height); RET( TRUE ); } static gint panel_size_alloc(GtkWidget *widget, GtkAllocation *a, panel *p) { ENTER; DBG("new alloc: size (%d, %d). pos (%d, %d)\n", a->width, a->height, a->x, a->y); DBG("old alloc: size (%d, %d). pos (%d, %d)\n", p->aw, p->ah, p->ax, p->ay); if (p->widthtype == WIDTH_REQUEST) p->width = (p->orientation == ORIENT_HORIZ) ? a->width : a->height; if (p->heighttype == HEIGHT_REQUEST) p->height = (p->orientation == ORIENT_HORIZ) ? a->height : a->width; calculate_position(p, distance,distancefrom); DBG("pref alloc: size (%d, %d). pos (%d, %d)\n", p->aw, p->ah, p->ax, p->ay); if (a->width == p->aw && a->height == p->ah && a->x == p->ax && a->y == p ->ay) { DBG("actual coords eq to preffered. just returning\n"); RET(TRUE); } gtk_window_move(GTK_WINDOW(p->topgwin), p->ax, p->ay); if (p->setstrut) panel_set_wm_strut(p); RET(TRUE); } /**************************************************** * panel creation * ****************************************************/ static void set_bg(GtkWidget *widget, panel *p) { ENTER; if (p->gtopbg) g_object_unref(p->gtopbg); p->gtopbg = bg_new_for_win(p->topxwin); modify_drawable(p->gtopbg, p->topgwin->style->black_gc, p->tintcolor, p->alpha); gdk_window_set_back_pixmap(p->topgwin->window, p->gtopbg, FALSE); gdk_window_clear(p->topgwin->window); gtk_widget_queue_draw_area (p->topgwin, 0, 0, 2000, 2000); RET(); } static void panel_style_set(GtkWidget *widget, GtkStyle *s, panel *p) { ENTER; gtk_rc_parse_string(transparent_rc); if (GTK_WIDGET_REALIZED(widget)) set_bg(widget, p); RET(); } static gboolean panel_configure_event(GtkWidget *widget, GdkEventConfigure *event, panel *p) { static gint x = 0, y = 0, width = 0, height = 0; ENTER; if (x == event->x && y == event->y && width == event->width && height == event->height) RET(FALSE); x = event->x; y = event->y; width = event->width; height = event->height; set_bg(widget, p); RET(FALSE); } static gboolean panel_monitors_changed(GdkScreen* s, panel* p) { ENTER; p->monitor = gdk_screen_get_primary_monitor(s); calculate_position(p, distance,distancefrom); gdk_window_move_resize(p->topgwin->window, p->ax, p->ay, p->aw, p->ah); if (p->setstrut) panel_set_wm_strut(p); RET(TRUE); } void panel_start_gui(panel *p) { ENTER; //gtk_rc_parse_string(transparent_rc); p->topgwin = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width(GTK_CONTAINER(p->topgwin), 0); gtk_window_set_resizable(GTK_WINDOW(p->topgwin), FALSE); gtk_window_set_wmclass(GTK_WINDOW(p->topgwin), "panel", "trayer"); gtk_window_set_title(GTK_WINDOW(p->topgwin), "panel"); gtk_window_set_position(GTK_WINDOW(p->topgwin), GTK_WIN_POS_CENTER); g_signal_connect ( G_OBJECT(p->topgwin) , "delete-event" , G_CALLBACK(panel_delete_event) , p); g_signal_connect ( G_OBJECT(p->topgwin) , "destroy-event", G_CALLBACK(panel_destroy_event), p); g_signal_connect ( G_OBJECT (p->topgwin), "size-request" , G_CALLBACK(panel_size_req) , p); g_signal_connect ( G_OBJECT (p->topgwin), "size-allocate", G_CALLBACK(panel_size_alloc), p); if (p->transparent) { g_signal_connect (G_OBJECT (p->topgwin), "configure-event", G_CALLBACK(panel_configure_event), p); g_signal_connect (G_OBJECT (p->topgwin), "style-set", G_CALLBACK( panel_style_set), p); } if (p->on_primary) { GdkDisplay *display = gdk_display_get_default (); GdkScreen *screen = gdk_display_get_screen(display, 0); g_signal_connect ( screen, "monitors-changed", G_CALLBACK(panel_monitors_changed), (gpointer)p ); p->monitor = gdk_screen_get_primary_monitor(screen); } gtk_widget_realize(p->topgwin); gdk_window_set_decorations(p->topgwin->window, 0); gtk_widget_set_app_paintable(p->topgwin, TRUE); p->lbox = p->my_box_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(p->lbox), 0); gtk_container_add(GTK_CONTAINER(p->topgwin), p->lbox); gtk_widget_show(p->lbox); if (p->allign == ALLIGN_RIGHT) { GtkWidget * expander = p->my_box_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(p->lbox), expander, TRUE, TRUE, 0); gtk_widget_show(expander); } p->box = p->my_box_new(FALSE, 1); gtk_container_set_border_width(GTK_CONTAINER(p->box), 1); gtk_box_pack_start(GTK_BOX(p->lbox), p->box, FALSE, TRUE, padding); gtk_widget_show(p->box); // get properties on topgwin p->topGdkWindow = gtk_widget_get_window(p->topgwin); p->topxwin = GDK_WINDOW_XWINDOW(GTK_WIDGET(p->topgwin)->window); bg_init(gdk_helper_display()); /* make our window unfocusable */ gdk_window_set_accept_focus(p->topGdkWindow,False); if (p->setdocktype) { gdk_window_set_type_hint(p->topGdkWindow,GDK_WINDOW_TYPE_HINT_DOCK); } Xclimsg(p->topxwin, a_NET_WM_DESKTOP, 0xFFFFFFFF, 0, 0, 0, 0); /************************/ /* Window Mapping Point */ gtk_widget_show_all(p->topgwin); Xclimsg(p->topxwin, a_NET_WM_DESKTOP, 0xFFFFFFFF, 0, 0, 0, 0); gdk_window_stick ( p->topGdkWindow); gdk_window_set_skip_pager_hint ( p->topGdkWindow, True ); gdk_window_set_skip_taskbar_hint ( p->topGdkWindow, True ); XSelectInput (gdk_helper_display(), GDK_ROOT_WINDOW(), PropertyChangeMask); XSelectInput (gdk_helper_display(), p->topxwin, PropertyChangeMask | FocusChangeMask | StructureNotifyMask); gdk_window_add_filter(gdk_get_default_root_window (), (GdkFilterFunc)panel_wm_events, p); calculate_position(p, distance,distancefrom); gdk_window_move_resize(p->topgwin->window, p->ax, p->ay, p->aw, p->ah); if (p->setstrut) panel_set_wm_strut(p); if (p->lower) XLowerWindow(gdk_helper_display(), p->topxwin); RET(); } static int panel_parse_global(panel *p) { ENTER; p->orientation = (p->edge == EDGE_TOP || p->edge == EDGE_BOTTOM) ? ORIENT_HORIZ : ORIENT_VERT; if (p->orientation == ORIENT_HORIZ) { p->my_box_new = gtk_hbox_new; } else { p->my_box_new = gtk_vbox_new; } if (p->width < 0) p->width = 100; if (p->widthtype == WIDTH_PERCENT && p->width > 100) p->width = 100; p->heighttype = HEIGHT_PIXEL; if (p->heighttype == HEIGHT_PIXEL) { if (p->height < PANEL_HEIGHT_MIN) { ERR( "height is bound by %i pixels\n", PANEL_HEIGHT_MIN ); p->height = PANEL_HEIGHT_MIN; } else if (p->height > PANEL_HEIGHT_MAX) { ERR( "height is bound by %i pixels\n", PANEL_HEIGHT_MAX ); p->height = PANEL_HEIGHT_MAX; } } panel_start_gui(p); RET(1); } int panel_start(panel *p) { /* parse global section */ ENTER; if (!panel_parse_global(p)) RET(0); if (!tray_constructor(p)) RET(0); gtk_widget_show_all(p->topgwin); RET(1); } void panel_stop(panel *p) { ENTER; tray_destructor(p); XSelectInput (gdk_helper_display(), GDK_ROOT_WINDOW(), NoEventMask); gdk_window_remove_filter(gdk_get_default_root_window (), (GdkFilterFunc)panel_wm_events, p); gtk_widget_destroy(p->topgwin); RET(); } void usage() { ENTER; printf("trayer %s - lightweight GTK2+ systray for UNIX desktops\n", version); printf("Command line options:\n"); printf(" -h -- print this help and exit\n"); printf(" -v -- print version and exit\n"); printf(" -l -- lower the window on startup\n"); printf(" --edge (default:bottom) \n"); printf(" --align (default:center)\n"); printf(" --margin (default:0)\n"); printf(" --widthtype (default:percent)\n"); printf(" --width (default:%i)\n",PANEL_WIDTH_DEFAULT); printf(" --heighttype (default:pixel)\n"); printf(" --height (default:%i)\n",PANEL_HEIGHT_DEFAULT); printf(" --SetDockType (default:true)\n"); printf(" --SetPartialStrut (default:true)\n"); printf(" --transparent (default:false)\n"); printf(" --alpha (default:127)\n"); printf(" --tint (default:0xFFFFFFFF)\n"); printf(" --distance (default:0)\n"); printf(" --distancefrom (default:top) \n"); printf(" --expand (default:true)\n"); printf(" --padding (default:0)\n"); printf(" --monitor (default:0)\n"); printf(" --iconspacing (default:0)\n"); } void handle_error(Display * d, XErrorEvent * ev) { char buf[256]; ENTER; XGetErrorText(gdk_helper_display(), ev->error_code, buf, 256); ERR( "trayer : X error: %s\n", buf); RET(); } int main(int argc, char *argv[], char *env[]) { int i; ENTER; setlocale(LC_CTYPE, ""); gtk_init(&argc, &argv); XSetLocaleModifiers(""); XSetErrorHandler((XErrorHandler) handle_error); // resolve xatoms resolve_atoms(); p = g_new0(panel, 1); memset(p, 0, sizeof(panel)); p->allign = ALLIGN_CENTER; p->edge = EDGE_BOTTOM; p->widthtype = WIDTH_PERCENT; p->width = PANEL_WIDTH_DEFAULT; p->heighttype = HEIGHT_PIXEL; p->height = PANEL_HEIGHT_DEFAULT; p->setdocktype = 1; p->setstrut = 0; p->transparent = 0; p->icon_spacing = 0; p->alpha = 127; p->tintcolor = 0xFFFFFFFF; p->xtopbg = None; p->monitor = 0; p->margin = 0; p->on_primary = 0; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { usage(); exit(0); } else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { printf("trayer %s\n", version); exit(0); } else if (!strcmp(argv[i], "-l")) { p->lower = 1; } else if (!strcmp(argv[i], "--edge")) { i++; if (i == argc) { ERR( "trayer: missing edge parameter value\n"); usage(); exit(1); } else { p->edge = str2num(edge_pair, argv[i], EDGE_NONE); } } else if (!strcmp(argv[i], "--align")) { i++; if (i == argc) { ERR( "trayer: missing align parameter value\n"); usage(); exit(1); } else { p->allign = str2num(allign_pair, argv[i], ALLIGN_NONE); } } else if (!strcmp(argv[i], "--margin")) { i++; if (i == argc) { ERR( "trayer: missing margin parameter value\n"); usage(); exit(1); } else { p->margin = atoi(argv[i]); } } else if (!strcmp(argv[i], "--widthtype")) { i++; if (i == argc) { ERR( "trayer: missing widthtype parameter value\n"); usage(); exit(1); } else { p->widthtype = str2num(width_pair, argv[i], WIDTH_NONE); } } else if (!strcmp(argv[i], "--width")) { i++; if (i == argc) { ERR( "trayer: missing width parameter value\n"); usage(); exit(1); } else { p->width = atoi(argv[i]); } } else if (!strcmp(argv[i], "--heighttype")) { i++; if (i == argc) { ERR( "trayer: missing heighttype parameter value\n"); usage(); exit(1); } else { p->heighttype = str2num(height_pair, argv[i], HEIGHT_NONE); } } else if (!strcmp(argv[i], "--height")) { i++; if (i == argc) { ERR( "trayer: missing height parameter value\n"); usage(); exit(1); } else { p->height = atoi(argv[i]); } } else if (!strcmp(argv[i], "--SetDockType")) { i++; if (i == argc) { ERR( "trayer: missing SetDockType parameter value\n"); usage(); exit(1); } else { p->setdocktype = str2num(bool_pair, argv[i], 0); } } else if (!strcmp(argv[i], "--SetPartialStrut")) { i++; if (i == argc) { ERR( "trayer: missing SetPartialStrut parameter value\n"); usage(); exit(1); } else { p->setstrut = str2num(bool_pair, argv[i], 0); } } else if (!strcmp(argv[i], "--transparent")) { i++; if (i == argc) { ERR( "trayer: missing transparent parameter value\n"); usage(); exit(1); } else { p->transparent = str2num(bool_pair, argv[i], 1); } } else if (!strcmp(argv[i], "--alpha")) { i++; if (i == argc) { ERR( "trayer: missing alpha parameter value\n"); usage(); exit(1); } else { p->alpha = atoi(argv[i]); } } else if (!strcmp(argv[i], "--tint")) { i++; if (i == argc) { ERR( "trayer: missing tint parameter value\n"); usage(); exit(1); } else { p->tintcolor = strtoul(argv[i], NULL, 0); } } else if (!strcmp(argv[i], "--distance")) { i++; if (i == argc) { ERR( "trayer: missing distance parameter value\n"); usage(); exit(1); } else { distance = atoi(argv[i]); } } else if (!strcmp(argv[i], "--distancefrom")) { i++; if (i == argc) { ERR( "trayer: missing distancefrom parameter value\n"); usage(); exit(1); } else { distancefrom = str2num(distancefrom_pair, argv[i], DISTANCEFROM_NONE); } } else if (!strcmp(argv[i], "--expand")) { i++; if (i == argc) { ERR( "trayer: missing expand parameter value\n"); usage(); exit(1); } else { expand = str2num(bool_pair, argv[i], 1); } } else if (!strcmp(argv[i], "--padding")) { i++; if (i == argc) { ERR( "trayer: missing padding parameter value\n"); usage(); exit(1); } else { padding = atoi(argv[i]); } } else if (!strcmp(argv[i], "--monitor")) { i++; if (i == argc) { ERR( "trayer: missing monitor parameter value\n"); usage(); exit(1); } else { if (g_ascii_isdigit(argv[i][0])) { p->monitor = atoi(argv[i]); } else if (!strcmp(argv[i], "primary")) { p->on_primary = 1; } } } else if (!strcmp(argv[i], "--iconspacing")) { i++; if (i == argc) { ERR( "trayer: missing icon padding parameter value\n"); usage(); exit(1); } else { p->icon_spacing = atoi(argv[i]); } } else { printf("trayer: unknown option - %s\n", argv[i]); usage(); exit(1); } } g_return_val_if_fail (p != NULL, 1); if (!panel_start(p)) { ERR( "trayer: can't start panel\n"); exit(1); } gtk_main(); panel_stop(p); g_free(p); exit(0); } trayer-srg-trayer-1.1.7/panel.h000066400000000000000000000067411307264730600164130ustar00rootroot00000000000000#ifndef PANEL_H #define PANEL_H #include #include #include #include "config.h" enum { ALLIGN_NONE, ALLIGN_LEFT, ALLIGN_RIGHT, ALLIGN_CENTER }; enum { EDGE_NONE, EDGE_LEFT, EDGE_RIGHT, EDGE_TOP, EDGE_BOTTOM }; enum { DISTANCEFROM_NONE, DISTANCEFROM_LEFT, DISTANCEFROM_RIGHT, DISTANCEFROM_TOP, DISTANCEFROM_BOTTOM }; enum { WIDTH_NONE, WIDTH_REQUEST, WIDTH_PIXEL, WIDTH_PERCENT }; enum { HEIGHT_NONE, HEIGHT_PIXEL, HEIGHT_REQUEST }; enum { ORIENT_NONE, ORIENT_VERT, ORIENT_HORIZ }; enum { POS_NONE, POS_START, POS_END }; #define PANEL_HEIGHT_DEFAULT 26 #define PANEL_HEIGHT_MAX 200 #define PANEL_HEIGHT_MIN 2 #define PANEL_WIDTH_DEFAULT 100 typedef struct { GtkWidget *topgwin; /* main panel window */ GdkWindow* topGdkWindow; // and it parent gdk window Window topxwin; /* and it X window */ GtkWidget *lbox; /* primary layout box */ GtkWidget *box; /* box that contains all plugins */ GtkWidget *(*my_box_new) (gboolean, gint); Pixmap xtopbg; GdkPixmap *gtopbg; int alpha; guint32 tintcolor; int ax, ay, aw, ah; /* actual location and size of a panel */ int allign, edge, margin; int orientation; int widthtype, width; int heighttype, height; int self_destroy : 1; int setdocktype : 1; int setstrut : 1; int transparent : 1; int on_primary : 1; int monitor; int icon_spacing; // Import from plugin structure gpointer priv; int expand; int padding; int lower; } panel; typedef struct { unsigned int modal : 1; unsigned int sticky : 1; unsigned int maximized_vert : 1; unsigned int maximized_horz : 1; unsigned int shaded : 1; unsigned int skip_taskbar : 1; unsigned int skip_pager : 1; unsigned int hidden : 1; unsigned int fullscreen : 1; unsigned int above : 1; unsigned int below : 1; } net_wm_state; typedef struct { unsigned int desktop : 1; unsigned int dock : 1; unsigned int toolbar : 1; unsigned int menu : 1; unsigned int utility : 1; unsigned int splash : 1; unsigned int dialog : 1; unsigned int normal : 1; } net_wm_window_type; extern Atom a_UTF8_STRING; extern Atom a_XROOTPMAP_ID; extern Atom a_WM_STATE; extern Atom a_WM_CLASS; extern Atom a_NET_WORKAREA; extern Atom a_NET_CLIENT_LIST; extern Atom a_NET_CLIENT_LIST_STACKING; extern Atom a_NET_NUMBER_OF_DESKTOPS; extern Atom a_NET_CURRENT_DESKTOP; extern Atom a_NET_DESKTOP_NAMES; extern Atom a_NET_ACTIVE_WINDOW; extern Atom a_NET_WM_STATE; extern Atom a_NET_WM_STATE_SKIP_TASKBAR; extern Atom a_NET_WM_STATE_SKIP_PAGER; extern Atom a_NET_WM_STATE_STICKY; extern Atom a_NET_WM_STATE_HIDDEN; extern Atom a_NET_WM_STATE_SHADED; #define a_NET_WM_STATE_REMOVE 0 /* remove/unset property */ #define a_NET_WM_STATE_ADD 1 /* add/set property */ #define a_NET_WM_STATE_TOGGLE 2 /* toggle property */ extern Atom a_NET_WM_WINDOW_TYPE; extern Atom a_NET_WM_WINDOW_TYPE_DESKTOP; extern Atom a_NET_WM_WINDOW_TYPE_DOCK; extern Atom a_NET_WM_WINDOW_TYPE_TOOLBAR; extern Atom a_NET_WM_WINDOW_TYPE_MENU; extern Atom a_NET_WM_WINDOW_TYPE_UTILITY; extern Atom a_NET_WM_WINDOW_TYPE_SPLASH; extern Atom a_NET_WM_WINDOW_TYPE_DIALOG; extern Atom a_NET_WM_WINDOW_TYPE_NORMAL; extern Atom a_NET_WM_DESKTOP; extern Atom a_NET_WM_NAME; extern Atom a_NET_WM_STRUT; extern Atom a_NET_WM_STRUT_PARTIAL; extern Atom a_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR; #endif