From c606a1a35a93c9482dee7fed595c9572f56cfc87 Mon Sep 17 00:00:00 2001 From: o9000 Date: Thu, 16 Jul 2015 20:20:23 +0200 Subject: [PATCH] systray: Separate reparenting from embedding --- src/systray/systraybar.c | 56 ++++++++++++++++++++++++++++++++++++++-- src/systray/systraybar.h | 3 +++ src/tint.c | 12 +++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/systray/systraybar.c b/src/systray/systraybar.c index 5591ecf..51b0867 100644 --- a/src/systray/systraybar.c +++ b/src/systray/systraybar.c @@ -609,6 +609,58 @@ gboolean reparent_icon(TrayWindow *traywin) 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 @@ gboolean reparent_icon(TrayWindow *traywin) 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 @@ gboolean reparent_icon(TrayWindow *traywin) 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); diff --git a/src/systray/systraybar.h b/src/systray/systraybar.h index e47f384..11b7d0c 100644 --- a/src/systray/systraybar.h +++ b/src/systray/systraybar.h @@ -50,6 +50,7 @@ typedef struct 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(); diff --git a/src/tint.c b/src/tint.c index 62951cd..1617b8f 100644 --- a/src/tint.c +++ b/src/tint.c @@ -1287,12 +1287,24 @@ start: 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: