From 21dcd195642692401f855ef07b239364b5ef0c1b Mon Sep 17 00:00:00 2001 From: Andreas Fink Date: Wed, 30 Dec 2009 23:27:31 +0000 Subject: [PATCH] *add* real transparency is now supported... most systray applications work out of the box. Some do not work yet, because they do not respect freedesktops standard --- src/config.c | 10 ++++++++++ src/panel.c | 23 +++++++---------------- src/panel.h | 2 ++ src/server.c | 2 ++ src/server.h | 1 + src/systray/systraybar.c | 2 ++ src/taskbar/taskbar.c | 2 +- src/tint.c | 11 ++++++----- src/tooltip/tooltip.c | 17 ++++++++++++----- src/util/area.c | 26 +++++++++++++++----------- src/util/area.h | 3 +++ 11 files changed, 61 insertions(+), 38 deletions(-) diff --git a/src/config.c b/src/config.c index cbb9d66..41d3f3f 100644 --- a/src/config.c +++ b/src/config.c @@ -293,6 +293,16 @@ void add_entry (char *key, char *value) panel_dock = atoi (value); else if (strcmp (key, "urgent_nb_of_blink") == 0) max_tick_urgent = (atoi (value) * 2) + 1; + else if (strcmp (key, "real_transparency") == 0) + real_transparency = atoi(value); + else if (strcmp (key, "panel_layer") == 0) { + if (strcmp(value, "bottom") == 0) + panel_layer = BOTTOM_LAYER; + else if (strcmp(value, "normal") == 0) + panel_layer = NORMAL_LAYER; + else if (strcmp(value, "top") == 0) + panel_layer = TOP_LAYER; + } /* Battery */ else if (strcmp (key, "battery") == 0) { diff --git a/src/panel.c b/src/panel.c index ee3e27d..34954f7 100644 --- a/src/panel.c +++ b/src/panel.c @@ -46,6 +46,7 @@ int mouse_tilt_right; int panel_mode; int wm_menu; int panel_dock=0; // default not in the dock +int panel_layer=BOTTOM_LAYER; // default is bottom layer int panel_position; int panel_horizontal; int panel_refresh; @@ -162,10 +163,7 @@ void init_panel() if (!server.gc) { XGCValues gcv; - if (real_transparency) - server.gc = XCreateGC(server.dsp, p->main_win, 0, &gcv); - else - server.gc = XCreateGC (server.dsp, server.root_win, (unsigned long)0, &gcv); + server.gc = XCreateGC(server.dsp, p->main_win, 0, &gcv); } //printf("panel %d : %d, %d, %d, %d\n", i, p->posx, p->posy, p->area.width, p->area.height); set_panel_properties(p); @@ -397,14 +395,14 @@ void set_panel_properties(Panel *p) XChangeProperty (server.dsp, p->main_win, server.atom._NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *) &val, 1); // Sticky and below other window - val = 0xFFFFFFFF; + val = ALLDESKTOP; XChangeProperty (server.dsp, p->main_win, server.atom._NET_WM_DESKTOP, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &val, 1); Atom state[4]; state[0] = server.atom._NET_WM_STATE_SKIP_PAGER; state[1] = server.atom._NET_WM_STATE_SKIP_TASKBAR; state[2] = server.atom._NET_WM_STATE_STICKY; - state[3] = server.atom._NET_WM_STATE_BELOW; - XChangeProperty (server.dsp, p->main_win, server.atom._NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *) state, 4); + state[3] = panel_layer == BOTTOM_LAYER ? server.atom._NET_WM_STATE_BELOW : server.atom._NET_WM_STATE_ABOVE; + XChangeProperty (server.dsp, p->main_win, server.atom._NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *) state, panel_layer == NORMAL_LAYER ? 3 : 4); // Unfocusable XWMHints wmhints; @@ -490,15 +488,8 @@ void set_panel_background(Panel *p) p->area.pix.pmap = XCreatePixmap (server.dsp, server.root_win, p->area.width, p->area.height, server.depth); if (real_transparency) { - cairo_surface_t *tmp = cairo_xlib_surface_create (server.dsp, p->area.pix.pmap, server.visual, p->area.width, p->area.height); - cairo_t *cr = cairo_create(tmp); - cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - cairo_rectangle(cr, 0, 0, p->area.width, p->area.height); - cairo_set_source_rgba(cr, 1, 1, 1, 0); - cairo_paint (cr); - cairo_destroy (cr); - cairo_surface_destroy (tmp); - return; + clear_pixmap(p->area.pix.pmap, 0, 0, p->area.width, p->area.height); + return; // no need for background pixmap, a transparent one is enough } get_root_pixmap(); diff --git a/src/panel.h b/src/panel.h index 73d7f50..52665cd 100644 --- a/src/panel.h +++ b/src/panel.h @@ -37,9 +37,11 @@ extern int mouse_tilt_right; //panel mode enum { SINGLE_DESKTOP=0, MULTI_DESKTOP }; +enum { BOTTOM_LAYER, NORMAL_LAYER, TOP_LAYER }; extern int panel_mode; extern int wm_menu; extern int panel_dock; +extern int panel_layer; //panel position enum { LEFT=0x01, RIGHT=0x02, CENTER=0X04, TOP=0X08, BOTTOM=0x10 }; diff --git a/src/server.c b/src/server.c index f843963..202af94 100644 --- a/src/server.c +++ b/src/server.c @@ -61,6 +61,7 @@ void server_init_atoms () server.atom._NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom (server.dsp, "_NET_WM_STATE_MAXIMIZED_HORZ", False); server.atom._NET_WM_STATE_SHADED = XInternAtom (server.dsp, "_NET_WM_STATE_SHADED", False); server.atom._NET_WM_STATE_BELOW = XInternAtom (server.dsp, "_NET_WM_STATE_BELOW", False); + server.atom._NET_WM_STATE_ABOVE = XInternAtom (server.dsp, "_NET_WM_STATE_ABOVE", False); server.atom._NET_WM_STATE_MODAL = XInternAtom (server.dsp, "_NET_WM_STATE_MODAL", False); server.atom._NET_CLIENT_LIST = XInternAtom (server.dsp, "_NET_CLIENT_LIST", False); server.atom._NET_WM_VISIBLE_NAME = XInternAtom (server.dsp, "_NET_WM_VISIBLE_NAME", False); @@ -307,6 +308,7 @@ void get_desktops() void server_init_visual() { + // inspired by freedesktops fdclock ;) XVisualInfo *xvi; XVisualInfo templ = { .screen=server.screen, .depth=32, .class=TrueColor }; int nvi; diff --git a/src/server.h b/src/server.h index 7a86ca4..d010875 100644 --- a/src/server.h +++ b/src/server.h @@ -41,6 +41,7 @@ typedef struct Global_atom Atom _NET_WM_STATE_MAXIMIZED_HORZ; Atom _NET_WM_STATE_SHADED; Atom _NET_WM_STATE_BELOW; + Atom _NET_WM_STATE_ABOVE; Atom _NET_WM_STATE_MODAL; Atom _NET_CLIENT_LIST; Atom _NET_WM_NAME; diff --git a/src/systray/systraybar.c b/src/systray/systraybar.c index 8543196..273d9bb 100644 --- a/src/systray/systraybar.c +++ b/src/systray/systraybar.c @@ -214,6 +214,8 @@ void start_net() // Vertical panel will draw the systray horizontal. int orient = 0; XChangeProperty(server.dsp, net_sel_win, server.atom._NET_SYSTEM_TRAY_ORIENTATION, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &orient, 1); + VisualID vid = XVisualIDFromVisual(server.visual); + XChangeProperty(server.dsp, net_sel_win, XInternAtom(server.dsp, "_NET_SYSTEM_TRAY_VISUAL", False), XA_VISUALID, 32, PropModeReplace, (unsigned char*)&vid, 1); XSetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN, net_sel_win, CurrentTime); if (XGetSelectionOwner(server.dsp, server.atom._NET_SYSTEM_TRAY_SCREEN) != net_sel_win) { diff --git a/src/taskbar/taskbar.c b/src/taskbar/taskbar.c index f7197c1..6ea6b4d 100644 --- a/src/taskbar/taskbar.c +++ b/src/taskbar/taskbar.c @@ -190,7 +190,7 @@ GSList* task_get_tasks(Window win) void task_refresh_tasklist () { - Window *win, active_win; + Window *win; int num_results, i, j, k; GSList *l0; Task *tsk; diff --git a/src/tint.c b/src/tint.c index 987003c..27458b8 100644 --- a/src/tint.c +++ b/src/tint.c @@ -61,7 +61,7 @@ void init (int argc, char *argv[]) printf("tint2 version 0.8\n"); exit(0); } - if (!strcmp(argv[i], "-c")) { + if (!strcmp(argv[i], "-c")) { i++; if (i < argc) config_path = strdup(argv[i]); @@ -91,7 +91,7 @@ void init (int argc, char *argv[]) // set global data memset(&server, 0, sizeof(Server_global)); - memset(&systray, 0, sizeof(Systraybar)); +// memset(&systray, 0, sizeof(Systraybar)); server.dsp = XOpenDisplay (NULL); if (!server.dsp) { @@ -679,10 +679,8 @@ int main (int argc, char *argv[]) GSList *it; const struct timespec* timeout; - init (argc, argv); - - i = 0; init_config(); + i = 0; if (config_path) i = config_read_file (config_path); else @@ -692,6 +690,9 @@ int main (int argc, char *argv[]) cleanup(); exit(1); } + + init (argc, argv); + init_panel(); cleanup_config(); if (snapshot_path) { diff --git a/src/tooltip/tooltip.c b/src/tooltip/tooltip.c index e63c1eb..d606047 100644 --- a/src/tooltip/tooltip.c +++ b/src/tooltip/tooltip.c @@ -215,13 +215,20 @@ void tooltip_update() cs = cairo_xlib_surface_create(server.dsp, g_tooltip.window, server.visual, width, height); c = cairo_create(cs); Color bc = g_tooltip.background_color; - cairo_rectangle(c, 0, 0, width, height); - cairo_set_source_rgba(c, bc.color[0], bc.color[1], bc.color[2], bc.alpha); - cairo_fill(c); Border b = g_tooltip.border; - cairo_set_source_rgba(c, b.color[0], b.color[1], b.color[2], b.alpha); + if (real_transparency) { + draw_rect(c, b.width, b.width, width-2*b.width, height-2*b.width, b.rounded-b.width/1.571); + cairo_set_source_rgba(c, bc.color[0], bc.color[1], bc.color[2], bc.alpha); + } + else { + cairo_rectangle(c, 0., 0, width, height); + cairo_set_source_rgb(c, bc.color[0], bc.color[1], bc.color[2]); + } + cairo_fill(c); cairo_set_line_width(c, b.width); - cairo_rectangle(c, b.width/2.0, b.width/2.0, width-b.width, height-b.width); + if (real_transparency) draw_rect(c, b.width/2.0, b.width/2.0, width - b.width, height - b.width, b.rounded); + else cairo_rectangle(c, b.width/2.0, b.width/2.0, width-b.width, height-b.width); + cairo_set_source_rgba(c, b.color[0], b.color[1], b.color[2], b.alpha); cairo_stroke(c); config_color fc = g_tooltip.font_color; diff --git a/src/util/area.c b/src/util/area.c index fc80a89..62bb2f2 100644 --- a/src/util/area.c +++ b/src/util/area.c @@ -107,17 +107,9 @@ void draw (Area *a, int active) if (*pmap) XFreePixmap (server.dsp, *pmap); *pmap = XCreatePixmap (server.dsp, server.root_win, a->width, a->height, server.depth); - // add layer of root pixmap - if (real_transparency) { - cairo_surface_t *tmp = cairo_xlib_surface_create (server.dsp, *pmap, server.visual, a->width, a->height); - cairo_t *cr = cairo_create(tmp); - cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - cairo_rectangle(cr, 0, 0, a->width, a->height); - cairo_set_source_rgba(cr, 1, 1, 1, 0); - cairo_paint (cr); - cairo_destroy (cr); - cairo_surface_destroy (tmp); - } + // add layer of root pixmap (or clear pixmap if real_transparency==true) + if (real_transparency) + clear_pixmap(*pmap, 0 ,0, a->width, a->height); else XCopyArea (server.dsp, ((Panel *)a->panel)->temp_pmap, *pmap, server.gc, a->posx, a->posy, a->width, a->height, 0, 0); @@ -259,3 +251,15 @@ void draw_rect(cairo_t *c, double x, double y, double w, double h, double r) } +void clear_pixmap(Pixmap p, int x, int y, int w, int h) +{ + cairo_surface_t *tmp = cairo_xlib_surface_create (server.dsp, p, server.visual, w, h); + cairo_t *cr = cairo_create(tmp); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_rectangle(cr, x, y, w, h); + cairo_set_source_rgba(cr, 1, 1, 1, 0); + cairo_fill(cr); + cairo_destroy(cr); + cairo_surface_destroy (tmp); + +} diff --git a/src/util/area.h b/src/util/area.h index a45b7b8..47c265a 100644 --- a/src/util/area.h +++ b/src/util/area.h @@ -102,5 +102,8 @@ void free_area (Area *a); // draw rounded rectangle void draw_rect(cairo_t *c, double x, double y, double w, double h, double r); + +// clear pixmap with transparent color +void clear_pixmap(Pixmap p, int x, int y, int w, int h); #endif -- 2.44.0