From 7efbab547aebbc8d883882cfa90ada0c59faa69d Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 28 May 2007 01:57:45 +0000 Subject: [PATCH] merge r6965-6971 from trunk --- openbox/client.c | 29 +++++++++++---- openbox/client.h | 3 ++ openbox/event.c | 46 ++++++++++++++--------- openbox/focus.c | 2 + openbox/focus_cycle.c | 13 ++++++- tests/duplicatesession.c | 66 +++++++++++++++++++++++++++++++++ tests/fakeunmap.c | 60 ++++++++++++++++++++++++++++++ tests/groupmodal.c | 80 ++++++++++++++++++++++++++++++++++++++++ tests/skiptaskbar.c | 64 ++++++++++++++++++++++++++++++++ 9 files changed, 336 insertions(+), 27 deletions(-) create mode 100644 tests/duplicatesession.c create mode 100644 tests/fakeunmap.c create mode 100644 tests/groupmodal.c create mode 100644 tests/skiptaskbar.c diff --git a/openbox/client.c b/openbox/client.c index 3f891b5a..5c025229 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -1122,13 +1122,16 @@ static void client_get_desktop(ObClient *self) self->desktop = screen_num_desktops - 1; else self->desktop = d; + ob_debug("client requested desktop 0x%x\n", self->desktop); } else { gboolean trdesk = FALSE; if (self->transient_for) { if (self->transient_for != OB_TRAN_GROUP) { - self->desktop = self->transient_for->desktop; - trdesk = TRUE; + if (self->transient_for->desktop != DESKTOP_ALL) { + self->desktop = self->transient_for->desktop; + trdesk = TRUE; + } } else { /* if all the group is on one desktop, then open it on the same desktop */ @@ -3460,6 +3463,10 @@ gboolean client_can_focus(ObClient *self) gboolean client_focus(ObClient *self) { + /* we might not focus this window, so if we have modal children which would + be focused instead, bring them to this desktop */ + client_bring_modal_windows(self); + /* choose the correct target */ self = client_focus_target(self); @@ -3579,15 +3586,18 @@ void client_activate(ObClient *self, gboolean here, gboolean user) client_hilite(self, TRUE); } -static void client_bring_helper_windows_recursive(ObClient *self, - guint desktop) +static void client_bring_windows_recursive(ObClient *self, + guint desktop, + gboolean helpers, + gboolean modals) { GSList *it; for (it = self->transients; it; it = g_slist_next(it)) - client_bring_helper_windows_recursive(it->data, desktop); + client_bring_windows_recursive(it->data, desktop, helpers, modals); - if (client_helper(self) && + if (((helpers && client_helper(self)) || + (modals && self->modal))&& self->desktop != desktop && self->desktop != DESKTOP_ALL) { client_set_desktop(self, desktop, FALSE); @@ -3596,7 +3606,12 @@ static void client_bring_helper_windows_recursive(ObClient *self, void client_bring_helper_windows(ObClient *self) { - client_bring_helper_windows_recursive(self, self->desktop); + client_bring_windows_recursive(self, self->desktop, TRUE, FALSE); +} + +void client_bring_modal_windows(ObClient *self) +{ + client_bring_windows_recursive(self, self->desktop, FALSE, TRUE); } gboolean client_focused(ObClient *self) diff --git a/openbox/client.h b/openbox/client.h index 755b973a..3d81b270 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -562,6 +562,9 @@ void client_activate(ObClient *self, gboolean here, gboolean user); stuff windows. */ void client_bring_helper_windows(ObClient *self); +/*! Bring all of its modal windows to its desktop. */ +void client_bring_modal_windows(ObClient *self); + /*! Calculates the stacking layer for the client window */ void client_calc_layer(ObClient *self); diff --git a/openbox/event.c b/openbox/event.c index bb249086..f3ed676e 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -270,6 +270,8 @@ static void event_hack_mods(XEvent *e) XEvent ce; while (XCheckTypedWindowEvent(ob_display, e->xmotion.window, e->type, &ce)) { + e->xmotion.x = ce.xmotion.x; + e->xmotion.y = ce.xmotion.y; e->xmotion.x_root = ce.xmotion.x_root; e->xmotion.y_root = ce.xmotion.y_root; } @@ -1006,8 +1008,12 @@ static void event_handle_client(ObClient *client, XEvent *e) RECT_TO_DIMS(client->area, x, y, w, h); b = client->border_width; - ob_debug("ConfigureRequest desktop %d wmstate %d visibile %d\n", - screen_desktop, client->wmstate, client->frame->visible); + ob_debug("ConfigureRequest for \"%s\" desktop %d wmstate %d " + "visibile %d\n" + " x %d y %d w %d h %d b %d\n", + client->title, + screen_desktop, client->wmstate, client->frame->visible, + x, y, w, h, b); if (e->xconfigurerequest.value_mask & CWBorderWidth) if (client->border_width != e->xconfigurerequest.border_width) { @@ -1036,10 +1042,10 @@ static void event_handle_client(ObClient *client, XEvent *e) move = TRUE; } - if (e->xconfigurerequest.value_mask & CWX || - e->xconfigurerequest.value_mask & CWY || - e->xconfigurerequest.value_mask & CWWidth || - e->xconfigurerequest.value_mask & CWHeight) + if ((e->xconfigurerequest.value_mask & CWX) || + (e->xconfigurerequest.value_mask & CWY) || + (e->xconfigurerequest.value_mask & CWWidth) || + (e->xconfigurerequest.value_mask & CWHeight)) { if (e->xconfigurerequest.value_mask & CWX) { /* don't allow clients to move shaded windows (fvwm does this) @@ -1059,20 +1065,10 @@ static void event_handle_client(ObClient *client, XEvent *e) if (e->xconfigurerequest.value_mask & CWWidth) { w = e->xconfigurerequest.width; resize = TRUE; - - /* if x was not given, then use gravity to figure out the new - x. the reference point should not be moved */ - if (!(e->xconfigurerequest.value_mask & CWX)) - client_gravity_resize_w(client, &x, client->area.width, w); } if (e->xconfigurerequest.value_mask & CWHeight) { h = e->xconfigurerequest.height; resize = TRUE; - - /* if y was not given, then use gravity to figure out the new - y. the reference point should not be moved */ - if (!(e->xconfigurerequest.value_mask & CWY)) - client_gravity_resize_h(client, &y, client->area.height,h); } } @@ -1116,8 +1112,20 @@ static void event_handle_client(ObClient *client, XEvent *e) gint lw,lh; if (move || resize) { - client_find_onscreen(client, &x, &y, w, h, FALSE); client_try_configure(client, &x, &y, &w, &h, &lw, &lh, FALSE); + + /* if x was not given, then use gravity to figure out the new + x. the reference point should not be moved */ + if ((e->xconfigurerequest.value_mask & CWWidth && + !(e->xconfigurerequest.value_mask & CWX))) + client_gravity_resize_w(client, &x, client->area.width, w); + /* if y was not given, then use gravity to figure out the new + y. the reference point should not be moved */ + if ((e->xconfigurerequest.value_mask & CWHeight && + !(e->xconfigurerequest.value_mask & CWY))) + client_gravity_resize_h(client, &y, client->area.height,h); + + client_find_onscreen(client, &x, &y, w, h, FALSE); } /* if they requested something that moves the window, or if the window is actually being changed then configure it and @@ -1125,7 +1133,9 @@ static void event_handle_client(ObClient *client, XEvent *e) if (move || !RECT_EQUAL_DIMS(client->area, x, y, w, h) || border) { - ob_debug("Doing configure\n"); + ob_debug("Granting ConfigureRequest x %d y %d w %d h %d " + "b %d\n", + x, y, w, h, b); client_configure(client, x, y, w, h, b, FALSE, TRUE); } diff --git a/openbox/focus.c b/openbox/focus.c index 59dd0d0d..87f589f2 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -166,6 +166,8 @@ ObClient* focus_fallback(gboolean allow_refocus, gboolean allow_pointer) focus_nothing(); new = focus_fallback_target(allow_refocus, allow_pointer, old); + /* get what was really focused */ + if (new) new = client_focus_target(new); return new; } diff --git a/openbox/focus_cycle.c b/openbox/focus_cycle.c index 46f5f058..7549fbe5 100644 --- a/openbox/focus_cycle.c +++ b/openbox/focus_cycle.c @@ -149,8 +149,17 @@ gboolean focus_cycle_target_valid(ObClient *ft, ft->modal || !ft->skip_taskbar); - /* it's not going to just send fous off somewhere else (modal window) */ - ok = ok && ft == client_focus_target(ft); + /* it's not going to just send focus off somewhere else (modal window), + unless that modal window is not one of our valid targets, then let + you choose this window and bring the modal one here */ + { + ObClient *cft = client_focus_target(ft); + ok = ok && (ft == cft || !focus_cycle_target_valid(cft, + iconic_windows, + all_desktops, + dock_windows, + desktop_windows)); + } return ok; } diff --git a/tests/duplicatesession.c b/tests/duplicatesession.c new file mode 100644 index 00000000..55f300e6 --- /dev/null +++ b/tests/duplicatesession.c @@ -0,0 +1,66 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + duplicatesession.c for the Openbox window manager + Copyright (c) 2003-2007 Dana Jansens + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#include +#include +#include +#include + +int main (int argc, char **argv) { + Display *display; + Window win1, win2; + XEvent report; + int x=10,y=10,h=100,w=400; + XSizeHints size; + XTextProperty name; + Atom sm_id, enc; + + display = XOpenDisplay(NULL); + + if (display == NULL) { + fprintf(stderr, "couldn't connect to X server :0\n"); + return 0; + } + + sm_id = XInternAtom(display,"SM_CLIENT_ID",False); + enc = XInternAtom(display,"STRING",False); + + win1 = XCreateWindow(display, RootWindow(display, 0), + x, y, w, h, 10, CopyFromParent, CopyFromParent, + CopyFromParent, 0, NULL); + win2 = XCreateWindow(display, RootWindow(display, 0), + x, y, w, h, 10, CopyFromParent, CopyFromParent, + CopyFromParent, 0, NULL); + + XSetWindowBackground(display,win1,WhitePixel(display,0)); + XSetWindowBackground(display,win2,BlackPixel(display,0)); + + XChangeProperty(display, win1, sm_id, enc, 8, + PropModeAppend, "abcdefg", strlen("abcdefg")); + XChangeProperty(display, win2, sm_id, enc, 8, + PropModeAppend, "abcdefg", strlen("abcdefg")); + + XFlush(display); + XMapWindow(display, win1); + XMapWindow(display, win2); + + while (1) + XNextEvent(display, &report); + + return 1; +} diff --git a/tests/fakeunmap.c b/tests/fakeunmap.c new file mode 100644 index 00000000..c1c698a2 --- /dev/null +++ b/tests/fakeunmap.c @@ -0,0 +1,60 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + fakeunmap.c for the Openbox window manager + Copyright (c) 2003-2007 Dana Jansens + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#include +#include +#include +#include + +int main () { + Display *display; + Window win; + XEvent report; + XEvent msg; + int x=50,y=50,h=100,w=400; + + display = XOpenDisplay(NULL); + + if (display == NULL) { + fprintf(stderr, "couldn't connect to X server :0\n"); + return 0; + } + + win = XCreateWindow(display, RootWindow(display, 0), + x, y, w, h, 10, CopyFromParent, CopyFromParent, + CopyFromParent, 0, NULL); + XSetWindowBackground(display,win,WhitePixel(display,0)); + + XMapWindow(display, win); + XFlush(display); + usleep(10000); + + msg.type = UnmapNotify; + msg.xunmap.display = display; + msg.xunmap.event = RootWindow(display, DefaultScreen(display)); + msg.xunmap.window = win; + msg.xunmap.from_configure = False; + XSendEvent(display, RootWindow(display, DefaultScreen(display)), False, + SubstructureRedirectMask|SubstructureNotifyMask, &msg); + usleep(10000); + + XUnmapWindow(display, win); + XSync(display, False); + + return 1; +} diff --git a/tests/groupmodal.c b/tests/groupmodal.c new file mode 100644 index 00000000..0f670c51 --- /dev/null +++ b/tests/groupmodal.c @@ -0,0 +1,80 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + grouptran.c for the Openbox window manager + Copyright (c) 2003-2007 Dana Jansens + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#include +#include +#include +#include + +int main () { + Display *display; + Window one, two, group; + XEvent report; + XWMHints *wmhints; + Atom state, modal; + + display = XOpenDisplay(NULL); + + if (display == NULL) { + fprintf(stderr, "couldn't connect to X server :0\n"); + return 0; + } + + state = XInternAtom(display, "_NET_WM_STATE", True); + modal = XInternAtom(display, "_NET_WM_STATE_MODAL", True); + + group = XCreateWindow(display, RootWindow(display, 0), + 0,0,1,1, 10, CopyFromParent, CopyFromParent, + CopyFromParent, 0, 0); + + one = XCreateWindow(display, RootWindow(display, 0), + 0,0,300,300, 10, CopyFromParent, CopyFromParent, + CopyFromParent, 0, 0); + two = XCreateWindow(display, RootWindow(display, 0), + 0,0,100,100, 10, CopyFromParent, CopyFromParent, + CopyFromParent, 0, 0); + + XSetWindowBackground(display,one,WhitePixel(display,0)); + XSetWindowBackground(display,two,BlackPixel(display,0)); + + XSetTransientForHint(display, two, RootWindow(display,0)); + XChangeProperty(display, two, state, XA_ATOM, 32, + PropModeReplace, (unsigned char*)&modal, 1); + + wmhints = XAllocWMHints(); + + wmhints->flags = WindowGroupHint; + wmhints->window_group = group; + + XSetWMHints(display, one, wmhints); + XSetWMHints(display, two, wmhints); + + XFree(wmhints); + + XMapWindow(display, one); + XFlush(display); + sleep(1); + XMapWindow(display, two); + XFlush(display); + + while (1) { + XNextEvent(display, &report); + } + + return 1; +} diff --git a/tests/skiptaskbar.c b/tests/skiptaskbar.c new file mode 100644 index 00000000..08c6c18e --- /dev/null +++ b/tests/skiptaskbar.c @@ -0,0 +1,64 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + modal.c for the Openbox window manager + Copyright (c) 2003-2007 Dana Jansens + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#include +#include +#include +#include + +int main () { + Display *display; + Window parent, child; + XEvent report; + Atom state, modal; + int x=10,y=10,h=400,w=400; + + display = XOpenDisplay(NULL); + + if (display == NULL) { + fprintf(stderr, "couldn't connect to X server :0\n"); + return 0; + } + + state = XInternAtom(display, "_NET_WM_STATE", True); + modal = XInternAtom(display, "_NET_WM_STATE_MODAL", True); + + parent = XCreateWindow(display, RootWindow(display, 0), + x, y, w, h, 10, CopyFromParent, CopyFromParent, + CopyFromParent, 0, 0); + child = XCreateWindow(display, RootWindow(display, 0), + x, y, w/2, h/2, 10, CopyFromParent, CopyFromParent, + CopyFromParent, 0, 0); + + XSetWindowBackground(display,parent,WhitePixel(display,0)); + XSetWindowBackground(display,child,BlackPixel(display,0)); + + XSetTransientForHint(display, child, parent); + XChangeProperty(display, child, state, XA_ATOM, 32, + PropModeReplace, (unsigned char*)&modal, 1); + + XMapWindow(display, parent); + XMapWindow(display, child); + XFlush(display); + + while (1) { + XNextEvent(display, &report); + } + + return 1; +} -- 2.34.1