From 1ecfdf52892197deb8e413504aeaa142cd683621 Mon Sep 17 00:00:00 2001 From: o9000 Date: Sun, 24 Jan 2016 13:39:52 +0100 Subject: [PATCH] Fix bad clear of panel pixmap when display compositing is disabled --- src/panel.c | 63 ++++++++++++------------------------------------- src/tint.c | 18 ++++++++++++++ src/util/area.c | 9 +++++-- src/util/area.h | 3 +++ 4 files changed, 43 insertions(+), 50 deletions(-) diff --git a/src/panel.c b/src/panel.c index 9794e1c..57b9a68 100644 --- a/src/panel.c +++ b/src/panel.c @@ -34,6 +34,8 @@ #include "panel.h" #include "tooltip.h" +void panel_clear_background(void *obj); + int signal_pending; MouseAction mouse_left; @@ -198,6 +200,7 @@ void init_panel() p->area.resize_needed = 1; p->area.size_mode = LAYOUT_DYNAMIC; p->area._resize = resize_panel; + p->area._clear = panel_clear_background; init_panel_size_and_position(p); // add children according to panel_items for (int k = 0; k < strlen(panel_items_order); k++) { @@ -688,21 +691,17 @@ void set_panel_properties(Panel *p) XFree(classhint); } -void set_panel_background(Panel *p) +void panel_clear_background(void *obj) { - if (p->area.pix) - XFreePixmap(server.display, p->area.pix); - p->area.pix = XCreatePixmap(server.display, server.root_win, p->area.width, p->area.height, server.depth); - + Panel *p = obj; int xoff = 0, yoff = 0; if (panel_horizontal && panel_position & BOTTOM) yoff = p->area.height - p->hidden_height; else if (!panel_horizontal && panel_position & RIGHT) xoff = p->area.width - p->hidden_width; - if (server.real_transparency) { - clear_pixmap(p->area.pix, 0, 0, p->area.width, p->area.height); - } else { + clear_pixmap(p->area.pix, 0, 0, p->area.width, p->area.height); + if (!server.real_transparency) { get_root_pixmap(); // copy background (server.root_pmap) in panel.area.pix Window dummy; @@ -715,48 +714,16 @@ void set_panel_background(Panel *p) XSetTSOrigin(server.display, server.gc, -x, -y); XFillRectangle(server.display, p->area.pix, server.gc, 0, 0, p->area.width, p->area.height); } +} - // draw background panel - cairo_surface_t *cs = cairo_xlib_surface_create(server.display, p->area.pix, server.visual, p->area.width, p->area.height); - cairo_t *c = cairo_create(cs); - draw_background(&p->area, c); - cairo_destroy(c); - cairo_surface_destroy(cs); +void set_panel_background(Panel *p) +{ + panel_clear_background(p); + schedule_redraw(&p->area); - if (panel_autohide) { - if (p->hidden_pixmap) - XFreePixmap(server.display, p->hidden_pixmap); - p->hidden_pixmap = XCreatePixmap(server.display, server.root_win, p->hidden_width, p->hidden_height, server.depth); - XCopyArea(server.display, - p->area.pix, - p->hidden_pixmap, - server.gc, - xoff, - yoff, - p->hidden_width, - p->hidden_height, - 0, - 0); - } - - // redraw panel's object - for (GList *l = p->area.children; l; l = l->next) { - Area *a = (Area *)l->data; - schedule_redraw(a); - } - - // reset task/taskbar 'state_pix' - Taskbar *taskbar; - for (int i = 0; i < p->num_desktops; i++) { - taskbar = &p->taskbar[i]; - schedule_redraw(&taskbar->area); - schedule_redraw(&taskbar->bar_name.area); - GList *l = taskbar->area.children; - if (taskbarname_enabled) - l = l->next; - for (; l; l = l->next) { - schedule_redraw((Area *)l->data); - } + if (p->hidden_pixmap) { + XFreePixmap(server.display, p->hidden_pixmap); + p->hidden_pixmap = 0; } } diff --git a/src/tint.c b/src/tint.c index 260348a..5504cd4 100644 --- a/src/tint.c +++ b/src/tint.c @@ -1484,6 +1484,24 @@ start: Panel *panel = &panels[i]; if (panel->is_hidden) { + if (!panel->hidden_pixmap) { + panel->hidden_pixmap = XCreatePixmap(server.display, server.root_win, panel->hidden_width, panel->hidden_height, server.depth); + int xoff = 0, yoff = 0; + if (panel_horizontal && panel_position & BOTTOM) + yoff = panel->area.height - panel->hidden_height; + else if (!panel_horizontal && panel_position & RIGHT) + xoff = panel->area.width - panel->hidden_width; + XCopyArea(server.display, + panel->area.pix, + panel->hidden_pixmap, + server.gc, + xoff, + yoff, + panel->hidden_width, + panel->hidden_height, + 0, + 0); + } XCopyArea(server.display, panel->hidden_pixmap, panel->main_win, diff --git a/src/util/area.c b/src/util/area.c index b7c3c3a..f2c2122 100644 --- a/src/util/area.c +++ b/src/util/area.c @@ -379,9 +379,14 @@ void draw(Area *a) a->pix_by_state[a->has_mouse_over_effect ? a->mouse_state : 0] = a->pix; // Add layer of root pixmap (or clear pixmap if real_transparency==true) - if (server.real_transparency) + if (!a->_clear) { clear_pixmap(a->pix, 0, 0, a->width, a->height); - XCopyArea(server.display, ((Panel *)a->panel)->temp_pmap, a->pix, server.gc, a->posx, a->posy, a->width, a->height, 0, 0); + if (!server.real_transparency) { + XCopyArea(server.display, ((Panel *)a->panel)->temp_pmap, a->pix, server.gc, a->posx, a->posy, a->width, a->height, 0, 0); + } + } else { + a->_clear(a); + } cairo_surface_t *cs = cairo_xlib_surface_create(server.display, a->pix, server.visual, a->width, a->height); cairo_t *c = cairo_create(cs); diff --git a/src/util/area.h b/src/util/area.h index dbc25ff..548fa2b 100644 --- a/src/util/area.h +++ b/src/util/area.h @@ -202,6 +202,9 @@ typedef struct Area { // Callbacks + // Called on draw before any drawing takes place, obj = pointer to the Area + void (*_clear)(void *obj); + // Called on draw, obj = pointer to the Area void (*_draw_foreground)(void *obj, cairo_t *c);