summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Spilsbury <sam.spilsbury@canonical.com>2011-02-10 02:27:28 +0800
committerSam Spilsbury <sam.spilsbury@canonical.com>2011-02-10 02:27:28 +0800
commit4b16d3a39a5aea67902ac5698b5e059057bae06e (patch)
treedd1d6cafbd5d46abec302932c23aab1c4f33e76d
parent0dbce759abde90f4447fe962ffd8a9e12a0cc48e (diff)
downloadunity-window-decorator-4b16d3a39a5aea67902ac5698b5e059057bae06e.tar.gz
unity-window-decorator-4b16d3a39a5aea67902ac5698b5e059057bae06e.tar.bz2
Add support for the switcher window being override-redirect
-rw-r--r--src/decorator.c15
-rw-r--r--src/events.c44
-rw-r--r--src/gtk-window-decorator.c29
-rw-r--r--src/gtk-window-decorator.h10
-rw-r--r--src/switcher.c38
-rw-r--r--src/wnck.c27
6 files changed, 120 insertions, 43 deletions
diff --git a/src/decorator.c b/src/decorator.c
index 294c935..42df084 100644
--- a/src/decorator.c
+++ b/src/decorator.c
@@ -654,21 +654,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/src/events.c b/src/events.c
index 0b2099b..667fd0d 100644
--- a/src/events.c
+++ b/src/events.c
@@ -856,11 +856,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)
@@ -888,9 +910,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);
@@ -908,9 +930,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);
@@ -971,18 +993,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/src/gtk-window-decorator.c b/src/gtk-window-decorator.c
index 53a1293..9f895d9 100644
--- a/src/gtk-window-decorator.c
+++ b/src/gtk-window-decorator.c
@@ -181,6 +181,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;
@@ -193,6 +194,9 @@ main (int argc, char *argv[])
GdkScreen *gdkscreen;
WnckScreen *screen;
gint i, j, status;
+ unsigned int nchildren;
+ Window root_ret, parent_ret;
+ Window *children = NULL;
gboolean replace = FALSE;
#ifdef USE_METACITY
@@ -389,9 +393,34 @@ main (int argc, char *argv[])
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);
+ }
+
+ /* 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);
}
diff --git a/src/gtk-window-decorator.h b/src/gtk-window-decorator.h
index 9b262c8..b26885d 100644
--- a/src/gtk-window-decorator.h
+++ b/src/gtk-window-decorator.h
@@ -462,6 +462,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;
@@ -552,6 +553,7 @@ void
restack_window (WnckWindow *win,
int stack_mode);
+void connect_window (WnckWindow *win);
/* blur.c */
@@ -751,9 +753,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/src/switcher.c b/src/switcher.c
index 046ea0a..ef603c5 100644
--- a/src/switcher.c
+++ b/src/switcher.c
@@ -257,20 +257,48 @@ 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);
+ /* 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 +447,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/src/wnck.c b/src/wnck.c
index a42ccc1..2b340ed 100644
--- a/src/wnck.c
+++ b/src/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",
@@ -641,12 +659,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);
}