diff options
-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 | ||||
-rw-r--r-- | kde/window-decorator-kde4/decorator.cpp | 79 | ||||
-rw-r--r-- | kde/window-decorator-kde4/switcher.cpp | 6 | ||||
-rw-r--r-- | kde/window-decorator-kde4/switcher.h | 2 | ||||
-rw-r--r-- | plugins/decor/src/decor.cpp | 67 | ||||
-rw-r--r-- | plugins/decor/src/decor.h | 4 | ||||
-rw-r--r-- | plugins/switcher/src/switcher.cpp | 3 | ||||
-rw-r--r-- | src/window.cpp | 1 |
14 files changed, 269 insertions, 75 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); } diff --git a/kde/window-decorator-kde4/decorator.cpp b/kde/window-decorator-kde4/decorator.cpp index 76ea414..5c4b062 100644 --- a/kde/window-decorator-kde4/decorator.cpp +++ b/kde/window-decorator-kde4/decorator.cpp @@ -174,6 +174,10 @@ bool KWD::Decorator::enableDecorations (Time timestamp) { QList <WId>::ConstIterator it; + unsigned int nchildren; + WId *children; + WId root, parent; + long int select; mDmSnTimestamp = timestamp; @@ -210,12 +214,33 @@ KWD::Decorator::enableDecorations (Time timestamp) foreach (WId id, KWindowSystem::windows ()) handleWindowAdded (id); + /* Find the switcher and add it too + * FIXME: Doing XQueryTree and then + * XGetWindowProperty on every window + * like this is really expensive, surely + * there is a better way to do this */ + + XQueryTree (QX11Info::display (), QX11Info::appRootWindow (), + &root, &parent, &children, &nchildren); + + for (unsigned int i = 0; i < nchildren; i++) + { + if (KWD::readWindowProperty (children[i], + Atoms::switchSelectWindow, &select)) + { + handleWindowAdded(children[i]); + break; + } + } + connect (Plasma::Theme::defaultTheme (), SIGNAL (themeChanged ()), SLOT (plasmaThemeChanged ())); // select for client messages XSelectInput (QX11Info::display (), QX11Info::appRootWindow (), - StructureNotifyMask | PropertyChangeMask); + SubstructureNotifyMask | + StructureNotifyMask | + PropertyChangeMask); return true; } @@ -361,7 +386,24 @@ KWD::Decorator::x11EventFilter (XEvent *xevent) if (status == DECOR_SELECTION_GIVE_UP) KApplication::exit (0); - break; + break; + case CreateNotify: + /* We only care about windows that aren't managed here */ + if (!KWindowSystem::hasWId (xevent->xcreatewindow.window)) + { + WId select; + + KWD::trapXError (); + XSelectInput (QX11Info::display (), xevent->xcreatewindow.window, + StructureNotifyMask | PropertyChangeMask); + KWD::popXError (); + + if (KWD::readWindowProperty (xevent->xcreatewindow.window, + Atoms::switchSelectWindow, + (long *) &select)) + handleWindowAdded (xevent->xcreatewindow.window); + } + case PropertyNotify: if (xevent->xproperty.atom == Atoms::netInputFrameWindow) { @@ -600,6 +642,7 @@ KWD::Decorator::handleWindowAdded (WId id) WId oframe = 0, iframe = 0; KWD::Window::Type type = KWD::Window::Normal; QWidgetList widgets; + QRect geometry; /* avoid adding any of our own top level windows */ foreach (QWidget *widget, QApplication::topLevelWidgets ()) { @@ -607,19 +650,6 @@ KWD::Decorator::handleWindowAdded (WId id) return; } - KWD::trapXError (); - KWindowInfo wInfo = KWindowSystem::windowInfo (id, NET::WMGeometry); - if (KWD::popXError ()) - return; - - if (!wInfo.valid ()) - return; - - QRect geometry = wInfo.geometry (); - - KWD::readWindowProperty (id, Atoms::netInputFrameWindow, (long *) &iframe); - KWD::readWindowProperty (id, Atoms::netOutputFrameWindow, (long *) &oframe); - if (KWD::readWindowProperty (id, Atoms::switchSelectWindow, (long *) &select)) { @@ -630,11 +660,28 @@ KWD::Decorator::handleWindowAdded (WId id) delete mSwitcher; mSwitcher = new Switcher (mCompositeWindow, id); } + + geometry = mSwitcher->geometry (); frame = None; } else { - KWindowInfo wInfo = KWindowSystem::windowInfo (id, NET::WMWindowType, 0); + KWindowInfo wInfo; + + KWD::trapXError (); + wInfo = KWindowSystem::windowInfo (id, NET::WMGeometry); + if (KWD::popXError ()) + return; + + if (!wInfo.valid ()) + return; + + KWD::readWindowProperty (id, Atoms::netInputFrameWindow, (long *) &iframe); + KWD::readWindowProperty (id, Atoms::netOutputFrameWindow, (long *) &oframe); + + geometry = wInfo.geometry (); + + wInfo = KWindowSystem::windowInfo (id, NET::WMWindowType, 0); switch (wInfo.windowType (~0)) { case NET::Normal: diff --git a/kde/window-decorator-kde4/switcher.cpp b/kde/window-decorator-kde4/switcher.cpp index 201457d..ad39854 100644 --- a/kde/window-decorator-kde4/switcher.cpp +++ b/kde/window-decorator-kde4/switcher.cpp @@ -147,6 +147,12 @@ KWD::Switcher::updateGeometry () updateWindowProperties (); } +const QRect & +KWD::Switcher::geometry () +{ + return mGeometry; +} + void KWD::Switcher::redrawPixmap () { diff --git a/kde/window-decorator-kde4/switcher.h b/kde/window-decorator-kde4/switcher.h index cb0c350..29fafd4 100644 --- a/kde/window-decorator-kde4/switcher.h +++ b/kde/window-decorator-kde4/switcher.h @@ -50,6 +50,8 @@ class Switcher void update (); void updateGeometry (); + const QRect & geometry (); + WId xid () const { return mId; diff --git a/plugins/decor/src/decor.cpp b/plugins/decor/src/decor.cpp index 4ce2228..341ab85 100644 --- a/plugins/decor/src/decor.cpp +++ b/plugins/decor/src/decor.cpp @@ -286,7 +286,6 @@ Decoration::create (Window id, int result, format; unsigned long n, nleft; unsigned char *data; - unsigned char *data_orig; long *prop; Pixmap pixmap = None; decor_extents_t border; @@ -699,12 +698,12 @@ DecorWindow::update (bool allowDecoration) case CompWindowTypeMenuMask: case CompWindowTypeNormalMask: if (window->mwmDecor () & (MwmDecorAll | MwmDecorTitle)) - decorate = window->frame () ? true : false; + decorate = window->frame ()? true : false; default: break; } - if (window->overrideRedirect ()) + if (window->overrideRedirect () && !isSwitcher) decorate = false; if (window->wmType () & (CompWindowTypeDockMask | CompWindowTypeDesktopMask)) @@ -716,6 +715,9 @@ DecorWindow::update (bool allowDecoration) decorate = false; } + if (isSwitcher) + decorate = true; + if (decorate) { if (decor && checkSize (decor)) @@ -918,6 +920,12 @@ DecorWindow::updateInputFrame () int bw = server.border () * 2; CompWindowExtents input; CompWindowExtents border; + Window parent; + + if (isSwitcher) + parent = screen->root (); + else + parent = window->frame (); if ((window->state () & MAXIMIZE_STATE) == MAXIMIZE_STATE) { @@ -935,6 +943,12 @@ DecorWindow::updateInputFrame () width = server.width () + input.left + input.right + bw; height = server.height ()+ input.top + input.bottom + bw; + if (isSwitcher) + { + x += window->x (); + y += window->y (); + } + if (window->shaded ()) height = input.top + input.bottom; @@ -947,7 +961,7 @@ DecorWindow::updateInputFrame () attr.event_mask = StructureNotifyMask; attr.override_redirect = true; - inputFrame = XCreateWindow (screen->dpy (), window->frame (), + inputFrame = XCreateWindow (screen->dpy (), parent, x, y, width, height, 0, CopyFromParent, InputOnly, CopyFromParent, CWOverrideRedirect | CWEventMask, @@ -1345,6 +1359,31 @@ DecorWindow::windowNotify (CompWindowNotify n) } void +DecorWindow::updateSwitcher () +{ + Atom actualType; + int actualFmt; + unsigned long nitems, nleft; + unsigned long *data; + + DECOR_SCREEN (screen); + + if (XGetWindowProperty (screen->dpy (), window->id (), + ds->decorSwitchWindowAtom, 0L, 1024L, + false, XA_WINDOW, &actualType, &actualFmt, + &nitems, &nleft, (unsigned char **) &data) == Success) + { + if (nitems == 1) + { + isSwitcher = true; + return; + } + } + + isSwitcher = false; +} + +void DecorScreen::handleEvent (XEvent *event) { Window activeWindow = screen->activeWindow (); @@ -1411,7 +1450,16 @@ DecorScreen::handleEvent (XEvent *event) switch (event->type) { case PropertyNotify: - if (event->xproperty.atom == winDecorAtom) + if (event->xproperty.atom == decorSwitchWindowAtom) + { + CompWindow *w = screen->findWindow (event->xproperty.window); + + DECOR_WINDOW (w); + + if (dw->isSwitcher && !event->xproperty.state == PropertyDelete) + dw->updateSwitcher (); + } + else if (event->xproperty.atom == winDecorAtom) { w = screen->findWindow (event->xproperty.window); if (w) @@ -1816,6 +1864,8 @@ DecorScreen::DecorScreen (CompScreen *s) : XInternAtom (s->dpy (), DECOR_TYPE_PIXMAP_ATOM_NAME, 0); decorTypeWindowAtom = XInternAtom (s->dpy (), DECOR_TYPE_WINDOW_ATOM_NAME, 0); + decorSwitchWindowAtom = + XInternAtom (s->dpy (), DECOR_SWITCH_WINDOW_ATOM_NAME, 0); requestFrameExtentsAtom = XInternAtom (s->dpy (), "_NET_REQUEST_FRAME_EXTENTS", 0); shadowColorAtom = @@ -1878,7 +1928,8 @@ DecorWindow::DecorWindow (CompWindow *w) : regions (), updateReg (true), unshading (false), - shading (false) + shading (false), + isSwitcher (false) { WindowInterface::setHandler (window); @@ -1890,7 +1941,9 @@ DecorWindow::DecorWindow (CompWindow *w) : GLWindowInterface::setHandler (gWindow); } - if (!w->overrideRedirect ()) + updateSwitcher (); + + if (!w->overrideRedirect () || isSwitcher) updateDecoration (); if (w->shaded () || w->isViewable ()) diff --git a/plugins/decor/src/decor.h b/plugins/decor/src/decor.h index c579265..cf33cc6 100644 --- a/plugins/decor/src/decor.h +++ b/plugins/decor/src/decor.h @@ -145,6 +145,7 @@ class DecorScreen : Atom requestFrameExtentsAtom; Atom shadowColorAtom; Atom shadowInfoAtom; + Atom decorSwitchWindowAtom; Window dmWin; int dmSupports; @@ -202,6 +203,8 @@ class DecorWindow : bool resizeTimeout (); + void updateSwitcher (); + public: CompWindow *window; @@ -233,6 +236,7 @@ class DecorWindow : bool unshading; bool shading; + bool isSwitcher; }; class DecorPluginVTable : diff --git a/plugins/switcher/src/switcher.cpp b/plugins/switcher/src/switcher.cpp index 7a25b9a..71eb54e 100644 --- a/plugins/switcher/src/switcher.cpp +++ b/plugins/switcher/src/switcher.cpp @@ -254,6 +254,7 @@ SwitchScreen::initiate (SwitchWindowSelection selection, attr.border_pixel = 0; attr.colormap = XCreateColormap (dpy, screen->root (), visual, AllocNone); + attr.override_redirect = true; popupWindow = XCreateWindow (dpy, screen->root (), @@ -261,7 +262,7 @@ SwitchScreen::initiate (SwitchWindowSelection selection, screen->height () / 2 - xsh.height / 2, (unsigned) xsh.width, (unsigned) xsh.height, 0, 32, InputOutput, visual, - CWBackPixel | CWBorderPixel | CWColormap, &attr); + CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect, &attr); XSetWMProperties (dpy, popupWindow, NULL, NULL, programArgv, programArgc, diff --git a/src/window.cpp b/src/window.cpp index 577892a..c40d5da 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -5733,6 +5733,7 @@ PrivateWindow::reparent () /* We don't care about client events on the frame, and listening for them * will probably end up fighting the client anyways, so disable them */ + attr.do_not_propagate_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | |