diff options
author | Sam Spilsbury <sam.spilsbury@canonical.com> | 2011-02-10 20:26:12 +0800 |
---|---|---|
committer | Sam Spilsbury <sam.spilsbury@canonical.com> | 2011-02-10 20:26:12 +0800 |
commit | 73499a21c1ec450eb70de8129185e0289f86d56f (patch) | |
tree | 53d4efe429ab403a205b0e5e3942cbefca362216 /gtk | |
parent | 561d030ab63f3888d1b7698a3c2a8c7ba8985b79 (diff) | |
download | compiz-with-glib-mainloop-73499a21c1ec450eb70de8129185e0289f86d56f.tar.gz compiz-with-glib-mainloop-73499a21c1ec450eb70de8129185e0289f86d56f.tar.bz2 |
Make the switcher window being override redirect.
Previously the switcher window was a normal managed window (which
the switcher plugin actually lied about, see SwitchWindow::managed),
such that the decorators could pick it up and draw the switcher
decoration. However now with reparenting, this means that whenever
we actually manage and unmanage the switcher window (eg with map
and unmap) it means we must also reparent the window, which floods
the server with requests and makes the switcher slow.
Since we don't interact with the switcher window, it makes no sense
to manage it like this, so make it override redirect
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/window-decorator/decorator.c | 15 | ||||
-rw-r--r-- | gtk/window-decorator/events.c | 44 | ||||
-rw-r--r-- | gtk/window-decorator/gtk-window-decorator.c | 41 | ||||
-rw-r--r-- | gtk/window-decorator/gtk-window-decorator.h | 12 | ||||
-rw-r--r-- | gtk/window-decorator/settings.c | 4 | ||||
-rw-r--r-- | gtk/window-decorator/switcher.c | 39 | ||||
-rw-r--r-- | gtk/window-decorator/wnck.c | 27 |
7 files changed, 131 insertions, 51 deletions
diff --git a/gtk/window-decorator/decorator.c b/gtk/window-decorator/decorator.c index 3bcaddd..b4fe58b 100644 --- a/gtk/window-decorator/decorator.c +++ b/gtk/window-decorator/decorator.c @@ -653,21 +653,6 @@ update_window_decoration (WnckWindow *win) update_window_decoration_size (win); update_event_windows (win); } - else - { - Window xid = wnck_window_get_xid (win); - Window select; - - if (get_window_prop (xid, select_window_atom, &select)) - { - /* force size update */ - d->context = NULL; - d->width = d->height = 0; - switcher_width = switcher_height = 0; - - update_switcher_window (win, select); - } - } } void diff --git a/gtk/window-decorator/events.c b/gtk/window-decorator/events.c index 6c3af32..1faec8b 100644 --- a/gtk/window-decorator/events.c +++ b/gtk/window-decorator/events.c @@ -859,11 +859,33 @@ event_filter_func (GdkXEvent *gdkxevent, GdkDisplay *gdkdisplay; XEvent *xevent = gdkxevent; gulong xid = 0; + Window select = 0; gdkdisplay = gdk_display_get_default (); xdisplay = GDK_DISPLAY_XDISPLAY (gdkdisplay); switch (xevent->type) { + case CreateNotify: + { + if (!wnck_window_get (xevent->xcreatewindow.window)) + { + GdkWindow *toplevel = gdk_window_foreign_new_for_display (gdkdisplay, + xevent->xcreatewindow.window); + + if (toplevel) + { + gdk_window_set_events (toplevel, + gdk_window_get_events (toplevel) | + GDK_PROPERTY_CHANGE_MASK); + + /* check if the window is a switcher and update accordingly */ + + if (get_window_prop (xevent->xcreatewindow.window, select_window_atom, &select)) + update_switcher_window (xevent->xcreatewindow.window, select); + } + } + } + break; case ButtonPress: case ButtonRelease: xid = (gulong) @@ -891,9 +913,9 @@ event_filter_func (GdkXEvent *gdkxevent, win = wnck_window_get (xid); if (win) { - Window frame, window; + Window frame; - if (!get_window_prop (xid, select_window_atom, &window)) + if (!get_window_prop (xid, select_window_atom, &select)) { if (get_window_prop (xid, frame_input_window_atom, &frame)) add_frame_window (win, frame, FALSE); @@ -911,9 +933,9 @@ event_filter_func (GdkXEvent *gdkxevent, win = wnck_window_get (xid); if (win) { - Window frame, window; + Window frame; - if (!get_window_prop (xid, select_window_atom, &window)) + if (!get_window_prop (xid, select_window_atom, &select)) { if (get_window_prop (xid, frame_output_window_atom, &frame)) add_frame_window (win, frame, TRUE); @@ -974,18 +996,10 @@ event_filter_func (GdkXEvent *gdkxevent, } else if (xevent->xproperty.atom == select_window_atom) { - WnckWindow *win; + Window select; - xid = xevent->xproperty.window; - - win = wnck_window_get (xid); - if (win) - { - Window select; - - if (get_window_prop (xid, select_window_atom, &select)) - update_switcher_window (win, select); - } + if (get_window_prop (xevent->xproperty.window, select_window_atom, &select)) + update_switcher_window (xevent->xproperty.window, select); } break; case DestroyNotify: diff --git a/gtk/window-decorator/gtk-window-decorator.c b/gtk/window-decorator/gtk-window-decorator.c index bde881a..93e38db 100644 --- a/gtk/window-decorator/gtk-window-decorator.c +++ b/gtk/window-decorator/gtk-window-decorator.c @@ -172,6 +172,7 @@ GdkPixmap *switcher_buffer_pixmap = NULL; gint switcher_width; gint switcher_height; Window switcher_selected_window = None; +decor_t *switcher_window = NULL; XRenderPictFormat *xformat_rgba; XRenderPictFormat *xformat_rgb; @@ -185,6 +186,9 @@ main (int argc, char *argv[]) WnckScreen *screen; gint i, j, status; gboolean replace = FALSE; + unsigned int nchildren; + Window root_ret, parent_ret; + Window *children = NULL; #ifdef USE_METACITY char *meta_theme = NULL; @@ -380,13 +384,38 @@ main (int argc, char *argv[]) selection_event_filter_func, NULL); - if (!minimal) - { - gdk_window_add_filter (NULL, - event_filter_func, - NULL); + if (!minimal) + { + GdkWindow *root = gdk_window_foreign_new_for_display (gdkdisplay, + gdk_x11_get_default_root_xwindow ()); + + gdk_window_add_filter (NULL, + event_filter_func, + NULL); + + XQueryTree (xdisplay, gdk_x11_get_default_root_xwindow (), + &root_ret, &parent_ret, &children, &nchildren); + + for (i = 0; i < nchildren; i++) + { + GdkWindow *toplevel = gdk_window_foreign_new_for_display (gdkdisplay, + children[i]); + + /* Need property notify on all windows */ + + gdk_window_set_events (toplevel, + gdk_window_get_events (toplevel) | + GDK_PROPERTY_CHANGE_MASK); + } - connect_screen (screen); + /* Need MapNotify on new windows */ + gdk_window_set_events (root, gdk_window_get_events (root) | + GDK_STRUCTURE_MASK | + GDK_PROPERTY_CHANGE_MASK | + GDK_VISIBILITY_NOTIFY_MASK | + GDK_SUBSTRUCTURE_MASK); + + connect_screen (screen); } if (!init_settings (screen)) diff --git a/gtk/window-decorator/gtk-window-decorator.h b/gtk/window-decorator/gtk-window-decorator.h index 861cba2..2bd8669 100644 --- a/gtk/window-decorator/gtk-window-decorator.h +++ b/gtk/window-decorator/gtk-window-decorator.h @@ -450,6 +450,7 @@ extern GdkPixmap *switcher_buffer_pixmap; extern gint switcher_width; extern gint switcher_height; extern Window switcher_selected_window; +extern decor_t *switcher_window; extern XRenderPictFormat *xformat_rgba; extern XRenderPictFormat *xformat_rgb; @@ -532,6 +533,9 @@ void restack_window (WnckWindow *win, int stack_mode); +void +connect_window (WnckWindow *win); + /* blur.c */ @@ -718,9 +722,15 @@ void draw_switcher_decoration (decor_t *d); gboolean -update_switcher_window (WnckWindow *win, +update_switcher_window (Window popup, Window selected); +decor_t * +switcher_window_opened (Window popup, Window selected); + +void +switcher_window_closed (); + /* events.c */ void diff --git a/gtk/window-decorator/settings.c b/gtk/window-decorator/settings.c index f158636..31cc3e9 100644 --- a/gtk/window-decorator/settings.c +++ b/gtk/window-decorator/settings.c @@ -54,7 +54,7 @@ shadow_property_changed (WnckScreen *s) result = XGetTextProperty (xdisplay, root, &shadow_color_xtp, compiz_shadow_color_atom); - + if (shadow_color_xtp.value) { int ret_count = 0; @@ -84,7 +84,7 @@ shadow_property_changed (WnckScreen *s) if (changed) decorations_changed (s); } - + #ifdef USE_GCONF static gboolean blur_settings_changed (GConfClient *client) diff --git a/gtk/window-decorator/switcher.c b/gtk/window-decorator/switcher.c index 046ea0a..6da0475 100644 --- a/gtk/window-decorator/switcher.c +++ b/gtk/window-decorator/switcher.c @@ -257,20 +257,49 @@ draw_switcher_decoration (decor_t *d) draw_switcher_foreground (d); } +void +switcher_window_closed () +{ + g_free (switcher_window); + switcher_window = NULL; +} + +/* Switcher is override-redirect now, we need to track + * it separately */ +decor_t * +switcher_window_opened (Window popup, Window window) +{ + decor_t *d; + + d = switcher_window = calloc (1, sizeof (decor_t)); + if (!d) + return NULL; + + return d; +} + + gboolean -update_switcher_window (WnckWindow *win, +update_switcher_window (Window popup, Window selected) { - decor_t *d = g_object_get_data (G_OBJECT (win), "decor"); + decor_t *d = switcher_window; GdkPixmap *pixmap, *buffer_pixmap = NULL; - gint height, width = 0; + unsigned int height, width = 0, border, depth; + int x, y; + Window root_return; WnckWindow *selected_win; Display *xdisplay; XRenderPictFormat *format; + if (!d) + d = switcher_window_opened (popup, selected); + xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - wnck_window_get_client_window_geometry (win, NULL, NULL, &width, NULL); + /* FIXME: Thats a round-trip */ + XGetGeometry (gdk_x11_get_default_xdisplay (), popup, &root_return, + &x, &y, &width, &height, &border, &depth); decor_get_default_layout (&switcher_context, width, 1, &d->border_layout); @@ -419,7 +448,7 @@ update_switcher_window (WnckWindow *win, d->width = width; d->height = height; - d->prop_xid = wnck_window_get_xid (win); + d->prop_xid = popup; queue_decor_draw (d); diff --git a/gtk/window-decorator/wnck.c b/gtk/window-decorator/wnck.c index a4794e5..fc5fd14 100644 --- a/gtk/window-decorator/wnck.c +++ b/gtk/window-decorator/wnck.c @@ -83,6 +83,7 @@ decorations_changed (WnckScreen *screen) GdkDisplay *gdkdisplay; GdkScreen *gdkscreen; GList *windows; + Window select; gdkdisplay = gdk_display_get_default (); gdkscreen = gdk_display_get_default_screen (gdkdisplay); @@ -96,6 +97,8 @@ decorations_changed (WnckScreen *screen) if (minimal) return; + /* Update all normal windows */ + windows = wnck_screen_get_windows (screen); while (windows != NULL) { @@ -115,6 +118,21 @@ decorations_changed (WnckScreen *screen) update_window_decoration (WNCK_WINDOW (windows->data)); windows = windows->next; } + + /* Update switcher window */ + + if (switcher_window && + get_window_prop (switcher_window->prop_xid, + select_window_atom, &select)) + { + decor_t *d = switcher_window; + /* force size update */ + d->context = NULL; + d->width = d->height = 0; + switcher_width = switcher_height = 0; + + update_switcher_window (d->prop_xid, select); + } } void @@ -438,7 +456,7 @@ remove_frame_window (WnckWindow *win) draw_list = g_slist_remove (draw_list, d); } -static void +void connect_window (WnckWindow *win) { g_signal_connect_object (win, "name_changed", @@ -543,12 +561,7 @@ window_opened (WnckScreen *screen, xid = wnck_window_get_xid (win); - if (get_window_prop (xid, select_window_atom, &window)) - { - d->prop_xid = wnck_window_get_xid (win); - update_switcher_window (win, window); - } - else if (get_window_prop (xid, frame_input_window_atom, &window)) + if (get_window_prop (xid, frame_input_window_atom, &window)) { add_frame_window (win, window, FALSE); } |