all repos — tint2 @ c606a1a35a93c9482dee7fed595c9572f56cfc87

fork of the tint2 desktop panel for my custom setup - only minimized windows across all desktops for the taskbar

systray: Separate reparenting from embedding
o9000 o9000
commit

c606a1a35a93c9482dee7fed595c9572f56cfc87

parent

9933399dc41277aed9443e6ca1a1a3b202f763b8

3 files changed, 69 insertions(+), 2 deletions(-)

jump to
M src/systray/systraybar.csrc/systray/systraybar.c

@@ -609,6 +609,58 @@ fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);

if (traywin->reparented) return TRUE; + // Watch for the icon trying to resize itself / closing again + XSync(server.dsp, False); + error = FALSE; + XErrorHandler old = XSetErrorHandler(window_error_handler); + if (systray_profile) + fprintf(stderr, "XSelectInput(server.dsp, traywin->win, StructureNotifyMask)\n"); + XSelectInput(server.dsp, traywin->win, StructureNotifyMask | PropertyChangeMask); + XSync(server.dsp, False); + XSetErrorHandler(old); + if (error != FALSE) { + fprintf(stderr, RED "systray %d: cannot embed icon for window %lu (%s) parent %lu pid %d\n" RESET, __LINE__, traywin->win, traywin->name, traywin->parent, traywin->pid); + remove_icon(traywin); + return FALSE; + } + + // Reparent + if (systray_profile) + fprintf(stderr, "XSync(server.dsp, False)\n"); + XSync(server.dsp, False); + error = FALSE; + old = XSetErrorHandler(window_error_handler); + if (systray_profile) + fprintf(stderr, "XReparentWindow(server.dsp, traywin->win, traywin->parent, 0, 0)\n"); + XWithdrawWindow(server.dsp, traywin->win, server.screen); + XReparentWindow(server.dsp, traywin->win, traywin->parent, 0, 0); + if (systray_profile) + fprintf(stderr, "XMoveResizeWindow(server.dsp, traywin->win = %ld, 0, 0, traywin->width = %d, traywin->height = %d)\n", traywin->win, traywin->width, traywin->height); + XMoveResizeWindow(server.dsp, traywin->win, 0, 0, traywin->width, traywin->height); + + XSync(server.dsp, False); + XSetErrorHandler(old); + if (error != FALSE) { + fprintf(stderr, RED "systray %d: cannot embed icon for window %lu (%s) parent %lu pid %d\n" RESET, __LINE__, traywin->win, traywin->name, traywin->parent, traywin->pid); + remove_icon(traywin); + return FALSE; + } + + traywin->reparented = 1; + + if (systray_profile) + fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name); + + return TRUE; +} + +gboolean embed_icon(TrayWindow *traywin) +{ + if (systray_profile) + fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name); + if (traywin->embedded) + return TRUE; + Panel* panel = systray.area.panel; // Watch for the icon trying to resize itself / closing again

@@ -617,7 +669,7 @@ error = FALSE;

XErrorHandler old = XSetErrorHandler(window_error_handler); if (systray_profile) fprintf(stderr, "XSelectInput(server.dsp, traywin->win, StructureNotifyMask)\n"); - XSelectInput(server.dsp, traywin->win, StructureNotifyMask); + XSelectInput(server.dsp, traywin->win, StructureNotifyMask | PropertyChangeMask); XSync(server.dsp, False); XSetErrorHandler(old); if (error != FALSE) {

@@ -741,7 +793,7 @@ if (systray_profile)

fprintf(stderr, "XSync(server.dsp, False)\n"); XSync(server.dsp, False); - traywin->reparented = 1; + traywin->embedded = 1; if (systray_profile) fprintf(stderr, "[%f] %s:%d win = %lu (%s)\n", profiling_get_time(), __FUNCTION__, __LINE__, traywin->win, traywin->name);
M src/systray/systraybar.hsrc/systray/systraybar.h

@@ -50,6 +50,7 @@ int chrono;

struct timespec time_last_render; int num_fast_renders; int reparented; + int embedded; char *name; } TrayWindow;

@@ -85,6 +86,8 @@ void stop_net();

void net_message(XClientMessageEvent *e); gboolean add_icon(Window id); +gboolean reparent_icon(TrayWindow *traywin); +gboolean embed_icon(TrayWindow *traywin); void remove_icon(TrayWindow *traywin); void refresh_systray_icons();
M src/tint.csrc/tint.c

@@ -1287,12 +1287,24 @@ event_configure_notify(&e);

break; case ReparentNotify: + fprintf(stderr, "ReparentNotify\n"); if (!systray_enabled) break; panel = (Panel*)systray.area.panel; if (e.xany.window == panel->main_win) // reparented to us break; // FIXME: 'reparent to us' badly detected => disabled + for (it = systray.list_icons; it; it = g_slist_next(it)) { + TrayWindow *traywin = (TrayWindow*)it->data; + if (traywin->win == e.xreparent.window) { + fprintf(stderr, "win\n"); + if (traywin->parent == e.xreparent.parent) { + fprintf(stderr, "parent\n"); + embed_icon(traywin); + } + break; + } + } break; case UnmapNotify: case DestroyNotify: