]> Dogcows Code - chaz/tint2/commitdiff
*fix* more systray modifications for nice looking icons in real transparency mode
authorAndreas Fink <andreas.fink85@googlemail.com>
Sun, 3 Jan 2010 00:33:07 +0000 (00:33 +0000)
committerAndreas Fink <andreas.fink85@googlemail.com>
Sun, 3 Jan 2010 00:33:07 +0000 (00:33 +0000)
*add* added new options to the sample files

15 files changed:
configure.ac
sample/black_single_desktop.tint2rc
sample/default.tint2rc
sample/horizontal_icon_only.tint2rc
sample/rounded_multi_desktop.tint2rc
sample/tint2rc
sample/vertical_icon_only.tint2rc
sample/white_single_desktop.tint2rc
src/panel.c
src/systray/systraybar.c
src/systray/systraybar.h
src/tint.c
src/util/area.c
src/util/common.c
src/util/common.h

index 369010a8e8310c41c1502323293e0ce7404e5af6..348888797dd9fe122fcf06315317c9fe720d8bd7 100644 (file)
@@ -66,7 +66,7 @@ PKG_CHECK_MODULES([GOBJECT2], [gobject-2.0])
 AC_SUBST(GOBJECT2_CFLAGS)
 AC_SUBST(GOBJECT2_LIBS)
 
-PKG_CHECK_MODULES([X11], [x11])
+PKG_CHECK_MODULES([X11], [x11 xdamage xcomposite])
 AC_SUBST(X11_CFLAGS)
 AC_SUBST(X11_LIBS)
 
index 82e55f5bff8a8f198881be887c385f4e364cdb55..7b5208c42d04b2fafa289c216a858f1eff27f5d3 100644 (file)
@@ -46,6 +46,9 @@ panel_padding = 0 0 2
 font_shadow = 0
 panel_background_id = 1
 wm_menu = 1
+panel_dock = 0
+real_transparency = 0
+panel_layer = bottom
 
 #---------------------------------------------
 # TASKBAR
index dddd2a7aa5b00963774bf2db6fbb4ac3b9713cff..07f3f2a295bab54bd93ee0f101fa29990b78375b 100644 (file)
@@ -40,6 +40,9 @@ panel_padding = 7 2 7
 font_shadow = 0
 panel_background_id = 0
 wm_menu = 1
+panel_dock = 0
+real_transparency = 0
+panel_layer = bottom
 
 #---------------------------------------------
 # TASKBAR
@@ -100,6 +103,9 @@ clock_background_id = 1
 #clock_lclick_command = xclock
 clock_rclick_command = orage
 #clock_tooltip = %A %d %B
+#time1_timezone = :US/Hawaii
+#time2_timezone = :Europe/Berlin
+#clock_tooltip_timezone = :/usr/share/zoneinfo/Europe/Paris
 
 #---------------------------------------------
 # TOOLTIP
index e0af81b66f2c4b430721b5d5c0c4800ee1ad322e..3a7a69cdfae41b51d00aa7f4c15f1420f4304d7d 100644 (file)
@@ -38,6 +38,9 @@ panel_padding = 5 2 0
 font_shadow = 0
 panel_background_id = 1
 wm_menu = 1
+panel_dock = 0
+real_transparency = 0
+panel_layer = bottom
 
 #---------------------------------------------
 # TASKBAR
@@ -98,6 +101,9 @@ clock_background_id = 0
 #clock_lclick_command = xclock
 clock_rclick_command = orage
 #clock_tooltip = %A %d %B
+#time1_timezone = :US/Hawaii
+#time2_timezone = :Europe/Berlin
+#clock_tooltip_timezone = :/usr/share/zoneinfo/Europe/Paris
 
 #---------------------------------------------
 # TOOLTIP
index 30584c443a0a5abba7431d5e55f58e434f6d3fe1..bc50885c46e648ab447379d077464cf8dff84a66 100644 (file)
@@ -36,6 +36,9 @@ panel_padding = 10 3 10
 font_shadow = 0
 panel_background_id = 1
 wm_menu = 1
+panel_dock = 0
+real_transparency = 0
+panel_layer = bottom
 
 #---------------------------------------------
 # TASKBAR
index 1c321b57c33c2acb7f9ec845a360414aa84c92f5..6a9e86fc86f61a9189c1cc4e4f8c57df6a60e199 100644 (file)
@@ -31,6 +31,9 @@ panel_padding = 7 0
 font_shadow = 0
 panel_background_id = 1
 wm_menu = 0
+panel_dock = 0
+real_transparency = 0
+panel_layer = bottom
 
 #---------------------------------------------
 # TASKBAR
@@ -76,6 +79,9 @@ clock_background_id = 0
 #clock_lclick_command = xclock
 clock_rclick_command = orage
 #clock_tooltip = %A %d %B
+#time1_timezone = :US/Hawaii
+#time2_timezone = :Europe/Berlin
+#clock_tooltip_timezone = :/usr/share/zoneinfo/Europe/Paris
 
 #---------------------------------------------
 # BATTERY
index ca9547e4891d45e93b3d7d457702cb4f2e984ea8..9ed5fd72e24ad23c04d390353ef55bca769c2606 100644 (file)
@@ -31,6 +31,9 @@ panel_padding = 2 0
 font_shadow = 0
 panel_background_id = 0
 wm_menu = 0
+panel_dock = 0
+real_transparency = 0
+panel_layer = bottom
 
 #---------------------------------------------
 # TASKBAR
@@ -76,6 +79,9 @@ clock_background_id = 1
 #clock_lclick_command = xclock
 #clock_rclick_command = orage
 #clock_tooltip = %A %d %B
+#time1_timezone = :US/Hawaii
+#time2_timezone = :Europe/Berlin
+#clock_tooltip_timezone = :/usr/share/zoneinfo/Europe/Paris
 
 #---------------------------------------------
 # BATTERY
index 79cb39de57541d72aca1f44afe8602bc2857e667..713bc0ad4116d40362c8adbb5a9e16c25db6e490 100644 (file)
@@ -36,6 +36,10 @@ panel_margin = 0 0
 panel_padding = 3 3 3 3
 font_shadow = 0
 panel_background_id = 3
+wm_menu = 1
+panel_dock = 0
+real_transparency = 0
+panel_layer = bottom
 
 
 #---------------------------------------------
@@ -82,6 +86,9 @@ time1_font = AvantGardeLTMedium 9 bold
 clock_font_color = #151515 60
 clock_padding = 4 0
 clock_tooltip = %A %d %B
+#time1_timezone = :US/Hawaii
+#time2_timezone = :Europe/Berlin
+#clock_tooltip_timezone = :/usr/share/zoneinfo/Europe/Paris
 
 #---------------------------------------------
 # BATTERY
index 34954f7eba02b56bc1e0679282a98bcfe15c13d4..8bb9f14a61292ce7e8159b14bd9572e727a6cf2e 100644 (file)
@@ -407,7 +407,6 @@ void set_panel_properties(Panel *p)
        // Unfocusable
        XWMHints wmhints;
        if (panel_dock) {
-               // TODO: Xdnd feature cannot be used in withdrawn state at the moment (at least GTK apps fail, qt seems to work)
                wmhints.icon_window = wmhints.window_group = p->main_win;
                wmhints.flags = StateHint | IconWindowHint;
                wmhints.initial_state = WithdrawnState;
index 02ed1b4ed20440b212fe422550be4399a363b210..38acd62bf22a38f2486346bf66a2e037a1f9c1ec 100644 (file)
@@ -25,6 +25,9 @@
 #include <string.h>
 #include <glib.h>
 #include <Imlib2.h>
+#include <X11/extensions/Xdamage.h>
+#include <X11/extensions/Xrender.h>
+#include <X11/extensions/Xcomposite.h>
 
 #include "systraybar.h"
 #include "server.h"
@@ -163,6 +166,7 @@ void resize_systray(void *obj)
 
                // position and size the icon window
                XMoveResizeWindow(server.dsp, traywin->id, traywin->x, traywin->y, icon_size, icon_size);
+               XResizeWindow(server.dsp, traywin->tray_id, icon_size, icon_size);
        }
 }
 
@@ -276,10 +280,10 @@ static gint compare_traywindows(gconstpointer a, gconstpointer b)
        const TrayWindow * traywin_b = (TrayWindow*)b;
        XTextProperty name_a, name_b;
 
-       if(XGetWMName(server.dsp, traywin_a->id, &name_a) == 0) {
+       if(XGetWMName(server.dsp, traywin_a->tray_id, &name_a) == 0) {
                return -1;
        }
-       else if(XGetWMName(server.dsp, traywin_b->id, &name_b) == 0) {
+       else if(XGetWMName(server.dsp, traywin_b->tray_id, &name_b) == 0) {
                XFree(name_a.value);
                return 1;
        }
@@ -300,17 +304,22 @@ gboolean add_icon(Window id)
        int hide = 0;
 
        error = FALSE;
+       int wrong_format = 0;
        old = XSetErrorHandler(window_error_handler);
        XWindowAttributes attr;
        XGetWindowAttributes(server.dsp, id, &attr);
-       if ( attr.depth != server.depth ) {
-               XSetWindowAttributes a;
-               a.background_pixmap = None;  // set to none, otherwise XReparentWindow fails...
-               a.background_pixel = 0;      // set background pixel to 0. Looks ugly, but at least the icon appears
-               // TODO: maybe the XShape extension can be used, to clip the icon
-               XChangeWindowAttributes(server.dsp, id, CWBackPixmap|CWBackPixel, &a);
-       }
-       XReparentWindow(server.dsp, id, panel->main_win, 0, 0);
+       XSetWindowAttributes set_attr;
+       wrong_format = (attr.depth != server.depth);
+       set_attr.colormap = attr.colormap;
+       set_attr.background_pixel = 0;
+       set_attr.border_pixel = 0;
+       unsigned long mask = CWColormap|CWBackPixel|CWBorderPixel;
+       Window parent_window;
+       if (real_transparency)
+               parent_window = XCreateWindow(server.dsp, panel->main_win, 0, 0, 30, 30, 0, attr.depth, InputOutput, attr.visual, mask, &set_attr);
+       else
+               parent_window = panel->main_win;
+       XReparentWindow(server.dsp, id, parent_window, 0, 0);
        XSync(server.dsp, False);
        XSetErrorHandler(old);
        if (error != FALSE) {
@@ -351,14 +360,19 @@ gboolean add_icon(Window id)
                e.xclient.data.l[0] = CurrentTime;
                e.xclient.data.l[1] = XEMBED_EMBEDDED_NOTIFY;
                e.xclient.data.l[2] = 0;
-               e.xclient.data.l[3] = panel->main_win;
+               e.xclient.data.l[3] = parent_window;
                e.xclient.data.l[4] = 0;
                XSendEvent(server.dsp, id, False, 0xFFFFFF, &e);
        }
 
        traywin = g_new0(TrayWindow, 1);
-       traywin->id = id;
+       if (real_transparency)
+               traywin->id = parent_window;
+       else
+               traywin->id = id;
+       traywin->tray_id = id;
        traywin->hide = hide;
+       traywin->wrong_format = wrong_format;
 
        if (systray.sort == 3)
                systray.list_icons = g_slist_prepend(systray.list_icons, traywin);
@@ -371,11 +385,17 @@ gboolean add_icon(Window id)
        //printf("add_icon id %lx, %d\n", id, g_slist_length(systray.list_icons));
 
        // watch for the icon trying to resize itself!
-       XSelectInput(server.dsp, traywin->id, StructureNotifyMask);
+       XSelectInput(server.dsp, traywin->tray_id, StructureNotifyMask);
+       if (real_transparency) {
+               XDamageCreate(server.dsp, traywin->id, XDamageReportRawRectangles);
+               XCompositeRedirectWindow(server.dsp, traywin->id, CompositeRedirectManual);
+       }
 
        // show the window
-       if (!traywin->hide)
+       if (!traywin->hide) {
                XMapRaised(server.dsp, traywin->id);
+               XMapRaised(server.dsp, traywin->tray_id);
+       }
 
        // changed in systray force resize on panel
        panel->area.resize = 1;
@@ -394,14 +414,16 @@ void remove_icon(TrayWindow *traywin)
        systray.area.redraw = 1;
        //printf("remove_icon id %lx, %d\n", traywin->id);
 
-       XSelectInput(server.dsp, traywin->id, NoEventMask);
+       XSelectInput(server.dsp, traywin->tray_id, NoEventMask);
 
        // reparent to root
        error = FALSE;
        old = XSetErrorHandler(window_error_handler);
        if (!traywin->hide)
                XUnmapWindow(server.dsp, traywin->id);
-       XReparentWindow(server.dsp, traywin->id, server.root_win, 0, 0);
+       XReparentWindow(server.dsp, traywin->tray_id, server.root_win, 0, 0);
+       if (traywin->id != traywin->tray_id)
+               XDestroyWindow(server.dsp, traywin->id);
        XSync(server.dsp, False);
        XSetErrorHandler(old);
        g_free(traywin);
@@ -440,6 +462,50 @@ void net_message(XClientMessageEvent *e)
 }
 
 
+void systray_render_icons(TrayWindow* traywin)
+{
+       // most systray icons support 32 bit depth, but some icons are still 24 bit.
+       // We create a heuristic mask for these icons, i.e. we get the rgb value in the top left corner, and
+       // mask out all pixel with the same rgb value
+
+       Picture picture_systray, picture_tray, picture_panel;
+       Drawable mask, tray_pixmap;
+       Panel* panel = systray.area.panel;
+       XWindowAttributes attr;
+       XGetWindowAttributes(server.dsp, traywin->id, &attr);
+       XRenderPictFormat *format = XRenderFindVisualFormat(server.dsp, attr.visual);
+       XRenderPictFormat *panel_format = XRenderFindVisualFormat(server.dsp, server.visual);
+       if (traywin->wrong_format) {
+               imlib_context_set_drawable(traywin->id);
+               Imlib_Image image = imlib_create_image_from_drawable(0, 0, 0, traywin->width, traywin->height, 0);
+               imlib_context_set_image(image);
+               imlib_image_set_has_alpha(1);
+               DATA32* data = imlib_image_get_data();
+               createHeuristicMask(data, traywin->width, traywin->height);
+               imlib_image_put_back_data(data);
+               imlib_render_pixmaps_for_whole_image(&tray_pixmap, &mask);
+               picture_tray = XRenderCreatePicture( server.dsp, tray_pixmap, panel_format, 0, 0);
+               Picture mask2 = XRenderCreatePicture( server.dsp, mask, XRenderFindStandardFormat(server.dsp, PictStandardA1), 0, 0);
+               picture_systray = XRenderCreatePicture( server.dsp, systray.area.pix.pmap, panel_format, 0, 0);
+               picture_panel = XRenderCreatePicture(server.dsp, panel->main_win, panel_format, 0, 0);
+               XRenderComposite(server.dsp, PictOpOver, picture_tray, mask2, picture_systray, 0, 0, 0, 0, traywin->x-systray.area.posx, traywin->y-systray.area.posy, traywin->width, traywin->height);
+               XRenderComposite(server.dsp, PictOpOver, picture_tray, mask2, picture_panel, 0, 0, 0, 0, traywin->x, traywin->y, traywin->width, traywin->height);
+               imlib_free_pixmap_and_mask(tray_pixmap);
+               imlib_free_image();
+       }
+       else {
+               picture_tray = XRenderCreatePicture( server.dsp, traywin->id, format, 0, 0);
+               picture_systray = XRenderCreatePicture( server.dsp, systray.area.pix.pmap, panel_format, 0, 0);
+               picture_panel = XRenderCreatePicture(server.dsp, panel->main_win, panel_format, 0, 0);
+               XRenderComposite(server.dsp, PictOpOver, picture_tray, None, picture_systray, 0, 0, 0, 0, traywin->x-systray.area.posx, traywin->y-systray.area.posy, traywin->width, traywin->height);
+               XRenderComposite(server.dsp, PictOpOver, picture_tray, None, picture_panel, 0, 0, 0, 0, traywin->x, traywin->y, traywin->width, traywin->height);
+       }
+       XRenderFreePicture(server.dsp, picture_systray);
+       XRenderFreePicture(server.dsp, picture_tray);
+       XRenderFreePicture(server.dsp, picture_panel);
+}
+
+
 void refresh_systray_icon()
 {
        TrayWindow *traywin;
@@ -447,8 +513,9 @@ void refresh_systray_icon()
        for (l = systray.list_icons; l ; l = l->next) {
                traywin = (TrayWindow*)l->data;
                if (traywin->hide) continue;
-               XClearArea(server.dsp, traywin->id, 0, 0, traywin->width, traywin->height, True);
+               if (real_transparency) systray_render_icons(traywin);
+               else XClearArea(server.dsp, traywin->id, 0, 0, traywin->width, traywin->height, False);
        }
+       if (real_transparency)
+               XFlush(server.dsp);
 }
-
-
index 9e3b99012c4a5ac073692e22ef7ac2c78a68d1df..a2dbabacf898dae14a154c56672a62a04bf7761a 100644 (file)
@@ -31,10 +31,12 @@ typedef struct {
 typedef struct
 {
        Window id;
+       Window tray_id;
        int x, y;
        int width, height;
        // TODO: manage icon's show/hide
        int hide;
+       int wrong_format;
 } TrayWindow;
 
 
index 27458b8d87a4569c4487179012f391d81cf141e7..8f17653145ac46989eee7373675a6f54dbcb441b 100644 (file)
@@ -27,6 +27,7 @@
 #include <X11/Xutil.h>
 #include <X11/Xatom.h>
 #include <X11/Xlocale.h>
+#include <X11/extensions/Xdamage.h>
 #include <Imlib2.h>
 #include <signal.h>
 
@@ -609,9 +610,10 @@ void event_configure_notify (Window win)
        GSList *l;
        for (l = systray.list_icons; l ; l = l->next) {
                traywin = (TrayWindow*)l->data;
-               if (traywin->id == win) {
+               if (traywin->tray_id == win) {
                        //printf("move tray %d\n", traywin->x);
                        XMoveResizeWindow(server.dsp, traywin->id, traywin->x, traywin->y, traywin->width, traywin->height);
+                       XResizeWindow(server.dsp, traywin->tray_id, traywin->width, traywin->height);
                        panel_refresh = 1;
                        return;
                }
@@ -701,6 +703,8 @@ int main (int argc, char *argv[])
                exit(0);
        }
 
+       int damage_event, damage_error;
+       XDamageQueryExtension(server.dsp, &damage_event, &damage_error);
        x11_fd = ConnectionNumber(server.dsp);
        XSync(server.dsp, False);
 
@@ -807,7 +811,7 @@ int main (int argc, char *argv[])
                                                if (e.xany.window == g_tooltip.window || !systray.area.on_screen)
                                                        break;
                                                for (it = systray.list_icons; it; it = g_slist_next(it)) {
-                                                       if (((TrayWindow*)it->data)->id == e.xany.window) {
+                                                       if (((TrayWindow*)it->data)->tray_id == e.xany.window) {
                                                                remove_icon((TrayWindow*)it->data);
                                                                break;
                                                        }
@@ -823,6 +827,10 @@ int main (int argc, char *argv[])
                                                        dnd_message(&e.xclient);
                                                }
                                                break;
+
+                                       default:
+                                               if (e.type == XDamageNotify+damage_event)
+                                                       systray.area.redraw = 1;
                                }
                        }
                }
index 62bb2f212ad720be929d4b0a211929611b298676..ae9c5413e3b87964eb2f599507fdfdd20e0e6c98 100644 (file)
@@ -261,5 +261,4 @@ void clear_pixmap(Pixmap p, int x, int y, int w, int h)
        cairo_fill(cr);
        cairo_destroy(cr);
        cairo_surface_destroy (tmp);
-
 }
index c0ca6c3ece563cad5261559ff630433163d10d79..c186d424fc66f42e52bceef06935f430069145d8 100644 (file)
@@ -234,3 +234,18 @@ void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright
        }
 }
 
+
+void createHeuristicMask(DATA32* data, int w, int h)
+{
+       unsigned char* udata = (unsigned char*)data;
+       int b = udata[0];
+       int g = udata[1];
+       int r = udata[2];
+       int i;
+       for (i=0; i<h*w; ++i) {
+               if ( abs(b-*udata)<5 && abs(g-*(udata+1))<5 && abs(r-*(udata+2))<5 ) {
+                       *(udata+3) = 0;
+               }
+               udata += 4;
+       }
+}
index c7eca860384af182767563d7990fecae52572057..7f8259bbd1b66fb340daaada83d90d6cb5a77781 100644 (file)
@@ -64,5 +64,6 @@ void get_color (char *hex, double *rgb);
 // adjust Alpha/Saturation/Brightness on an ARGB icon
 // alpha from 0 to 100, satur from 0 to 1, bright from 0 to 1.
 void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright);
+void createHeuristicMask(DATA32* data, int w, int h);
 #endif
 
This page took 0.036757 seconds and 4 git commands to generate.