From: Dana Jansens Date: Fri, 11 May 2007 02:49:06 +0000 (+0000) Subject: merge r6315-6319 from trunk X-Git-Tag: openbox-3_3_991-RELEASE~100 X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=31d4ca6f656d66a91baa52af7aad41ce37ba2a25;p=dana%2Fopenbox.git merge r6315-6319 from trunk --- diff --git a/openbox/client.c b/openbox/client.c index f41c7558..e06fa291 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -282,30 +282,13 @@ void client_manage(Window window) /* non-zero defaults */ self->wmstate = WithdrawnState; /* make sure it gets updated first time */ + self->gravity = NorthWestGravity; self->desktop = screen_num_desktops; /* always an invalid value */ self->user_time = focus_client ? focus_client->user_time : CurrentTime; + /* get all the stuff off the window */ client_get_all(self, TRUE); - /* per-app settings override stuff, and return the settings for other - uses too */ - settings = client_get_settings_state(self); - /* the session should get the last say */ - client_restore_session_state(self); - - client_setup_decor_and_functions(self); - - { - Time t = sn_app_started(self->startup_id, self->class); - if (t) self->user_time = t; - } - /* update the focus lists, do this before the call to change_state or - it can end up in the list twice! */ - focus_order_add_new(self); - - /* remove the client's border (and adjust re gravity) */ - client_toggle_border(self, FALSE); - /* specify that if we exit, the window should not be destroyed and should be reparented back to root automatically */ XChangeSaveSet(ob_display, window, SetModeInsert); @@ -315,11 +298,33 @@ void client_manage(Window window) frame_grab_client(self->frame); + /* we've grabbed everything and set everything that we need to at mapping + time now */ + grab_server(FALSE); + + /* per-app settings override stuff from client_get_all, and return the + settings for other uses too */ + settings = client_get_settings_state(self); + /* the session should get the last say thought */ + client_restore_session_state(self); + + /* now we have all of the window's information so we can set this up */ + client_setup_decor_and_functions(self); + + /* remove the client's border (and adjust re gravity) */ + client_toggle_border(self, FALSE); + + { + Time t = sn_app_started(self->startup_id, self->class); + if (t) self->user_time = t; + } + /* do this after we have a frame.. it uses the frame to help determine the WM_STATE to apply. */ client_change_state(self); - grab_server(FALSE); + /* add ourselves to the focus order */ + focus_order_add_new(self); /* do this to add ourselves to the stacking list in a non-intrusive way */ client_calc_layer(self); @@ -453,6 +458,9 @@ void client_manage(Window window) stacking_raise(CLIENT_AS_WINDOW(self)); } + /* adjust the frame to the client's size before showing the window */ + frame_adjust_area(self->frame, FALSE, TRUE, FALSE); + /* this has to happen before we try focus the window, but we want it to happen after the client's stacking has been determined or it looks bad */ @@ -594,7 +602,12 @@ void client_unmanage(ObClient *self) /* restore the window's original geometry so it is not lost */ { - Rect a = self->area; + Rect a; + + /* give the client its border back */ + client_toggle_border(self, TRUE); + + a = self->area; if (self->fullscreen) a = self->pre_fullscreen_area; @@ -609,9 +622,6 @@ void client_unmanage(ObClient *self) } } - /* give the client its border back */ - client_toggle_border(self, TRUE); - self->fullscreen = self->max_horz = self->max_vert = FALSE; self->decorations = 0; /* unmanaged windows have no decor */ @@ -2657,12 +2667,11 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h, - gboolean user, gboolean final, - gboolean force_reply) + gboolean user, gboolean final) { - gint oldw, oldh, oldrx, oldry; + gint oldw, oldh; gboolean send_resize_client; - gboolean moved = FALSE, resized = FALSE, rootmoved = FALSE; + gboolean moved = FALSE, resized = FALSE; guint fdecor = self->frame->decorations; gboolean fhorz = self->frame->max_horz; gint logicalw, logicalh; @@ -2702,17 +2711,7 @@ void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h, if (moved || resized) frame_adjust_area(self->frame, moved, resized, FALSE); - /* find the client's position relative to the root window */ - oldrx = self->root_pos.x; - oldry = self->root_pos.y; - rootmoved = (oldrx != (signed)(self->frame->area.x + - self->frame->size.left - - self->border_width) || - oldry != (signed)(self->frame->area.y + - self->frame->size.top - - self->border_width)); - - if (force_reply || ((!user || (user && final)) && rootmoved)) + if ((!user || (user && final)) && !resized) { XEvent event; @@ -2727,6 +2726,9 @@ void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h, event.xconfigure.event = self->window; event.xconfigure.window = self->window; + ob_debug("Sending ConfigureNotify to %s for %d,%d %dx%d\n", + self->title, self->root_pos.x, self->root_pos.y, w, h); + /* root window real coords */ event.xconfigure.x = self->root_pos.x; event.xconfigure.y = self->root_pos.y; diff --git a/openbox/client.h b/openbox/client.h index aa7f41a5..bc7c32e8 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -166,7 +166,7 @@ struct _ObClient The window manager will set this to 0 while the window is being managed, but needs to restore it afterwards, so it is saved here. */ - guint border_width; + gint border_width; /*! The minimum aspect ratio the client window can be sized to. A value of 0 means this is ignored. @@ -375,7 +375,7 @@ void client_convert_gravity(ObClient *self, gint gravity, gint *x, gint *y, client_configure(self, x, y, w, h, TRUE, TRUE) #define client_configure(self, x, y, w, h, user, final) \ - client_configure_full(self, x, y, w, h, user, final, FALSE) + client_configure_full(self, x, y, w, h, user, final) /*! Figure out where a window will end up and what size it will be if you told it to move/resize to these coordinates. @@ -417,8 +417,7 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, the position changed. */ void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h, - gboolean user, gboolean final, - gboolean force_reply); + gboolean user, gboolean final); void client_reconfigure(ObClient *self); diff --git a/openbox/event.c b/openbox/event.c index c529f156..c0714882 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -950,70 +950,33 @@ static void event_handle_client(ObClient *client, XEvent *e) break; } case ConfigureRequest: + { /* dont compress these unless you're going to watch for property notifies in between (these can change what the configure would do to the window). also you can't compress stacking events */ - ob_debug("ConfigureRequest desktop %d wmstate %d vis %d\n", - screen_desktop, client->wmstate, client->frame->visible); + gint x, y, w, h; - /* don't allow clients to move shaded windows (fvwm does this) */ - if (client->shaded) { - e->xconfigurerequest.value_mask &= ~CWX; - e->xconfigurerequest.value_mask &= ~CWY; - } + /* if nothing is changed, then a configurenotify is needed */ + gboolean config = TRUE; - /* resize, then move, as specified in the EWMH section 7.7 */ - if (e->xconfigurerequest.value_mask & (CWWidth | CWHeight | - CWX | CWY | - CWBorderWidth)) { - gint x, y, w, h; + x = client->area.x; + y = client->area.y; + w = client->area.width; + h = client->area.height; - if (e->xconfigurerequest.value_mask & CWBorderWidth) - client->border_width = e->xconfigurerequest.border_width; + ob_debug("ConfigureRequest desktop %d wmstate %d visibile %d\n", + screen_desktop, client->wmstate, client->frame->visible); - x = (e->xconfigurerequest.value_mask & CWX) ? - e->xconfigurerequest.x : client->area.x; - y = (e->xconfigurerequest.value_mask & CWY) ? - e->xconfigurerequest.y : client->area.y; - w = (e->xconfigurerequest.value_mask & CWWidth) ? - e->xconfigurerequest.width : client->area.width; - h = (e->xconfigurerequest.value_mask & CWHeight) ? - e->xconfigurerequest.height : client->area.height; - - ob_debug("ConfigureRequest x %d %d y %d %d\n", - e->xconfigurerequest.value_mask & CWX, x, - e->xconfigurerequest.value_mask & CWY, y); - - /* check for broken apps moving to their root position - - XXX remove this some day...that would be nice. right now all - kde apps do this when they try activate themselves on another - desktop. eg. open amarok window on desktop 1, switch to desktop - 2, click amarok tray icon. it will move by its decoration size. - */ - if (x != client->area.x && - x == (client->frame->area.x + client->frame->size.left - - (gint)client->border_width) && - y != client->area.y && - y == (client->frame->area.y + client->frame->size.top - - (gint)client->border_width)) - { - ob_debug_type(OB_DEBUG_APP_BUGS, - "Application %s is trying to move via " - "ConfigureRequest to it's root window position " - "but it is not using StaticGravity\n", - client->title); - /* don't move it */ - x = client->area.x; - y = client->area.y; + if (e->xconfigurerequest.value_mask & CWBorderWidth) + if (client->border_width != e->xconfigurerequest.border_width) { + client->border_width = e->xconfigurerequest.border_width; + /* if only the border width is changing, then it's not needed*/ + config = FALSE; } - client_find_onscreen(client, &x, &y, w, h, FALSE); - client_configure_full(client, x, y, w, h, FALSE, TRUE, TRUE); - } if (e->xconfigurerequest.value_mask & CWStackMode) { ObClient *sibling = NULL; @@ -1030,8 +993,78 @@ static void event_handle_client(ObClient *client, XEvent *e) /* activate it rather than just focus it */ stacking_restack_request(client, sibling, e->xconfigurerequest.detail, TRUE); + + /* if a stacking change is requested then it is needed */ + config = TRUE; + } + + /* don't allow clients to move shaded windows (fvwm does this) */ + if (client->shaded && (e->xconfigurerequest.value_mask & CWX || + e->xconfigurerequest.value_mask & CWY)) + { + e->xconfigurerequest.value_mask &= ~CWX; + e->xconfigurerequest.value_mask &= ~CWY; + + /* if the client tried to move and we aren't letting it then a + synthetic event is needed */ + config = 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) + x = e->xconfigurerequest.x; + if (e->xconfigurerequest.value_mask & CWY) + y = e->xconfigurerequest.y; + if (e->xconfigurerequest.value_mask & CWWidth) + w = e->xconfigurerequest.width; + if (e->xconfigurerequest.value_mask & CWHeight) + h = e->xconfigurerequest.height; + + /* if a new position or size is requested, then a configure is + needed */ + config = TRUE; + } + + ob_debug("ConfigureRequest x(%d) %d y(%d) %d w(%d) %d h(%d) %d\n", + e->xconfigurerequest.value_mask & CWX, x, + e->xconfigurerequest.value_mask & CWY, y, + e->xconfigurerequest.value_mask & CWWidth, w, + e->xconfigurerequest.value_mask & CWHeight, h); + + /* check for broken apps moving to their root position + + XXX remove this some day...that would be nice. right now all + kde apps do this when they try activate themselves on another + desktop. eg. open amarok window on desktop 1, switch to desktop + 2, click amarok tray icon. it will move by its decoration size. + */ + if (x != client->area.x && + x == (client->frame->area.x + client->frame->size.left - + (gint)client->border_width) && + y != client->area.y && + y == (client->frame->area.y + client->frame->size.top - + (gint)client->border_width)) + { + ob_debug_type(OB_DEBUG_APP_BUGS, + "Application %s is trying to move via " + "ConfigureRequest to it's root window position " + "but it is not using StaticGravity\n", + client->title); + /* don't move it */ + x = client->area.x; + y = client->area.y; + } + + if (config) { + client_find_onscreen(client, &x, &y, w, h, FALSE); + client_configure_full(client, x, y, w, h, FALSE, TRUE); } break; + } case UnmapNotify: if (client->ignore_unmaps) { client->ignore_unmaps--; @@ -1237,6 +1270,13 @@ static void event_handle_client(ObClient *client, XEvent *e) /* just raise, don't activate */ stacking_restack_request(client, sibling, e->xclient.data.l[2], FALSE); + /* send a synthetic ConfigureNotify, cuz this is supposed + to be like a ConfigureRequest. */ + client_configure_full(client, client->area.x, + client->area.y, + client->area.width, + client->area.height, + FALSE, TRUE); } else ob_debug_type(OB_DEBUG_APP_BUGS, "_NET_RESTACK_WINDOW sent for window %s " diff --git a/openbox/frame.c b/openbox/frame.c index 5fd36714..68a64342 100644 --- a/openbox/frame.c +++ b/openbox/frame.c @@ -576,9 +576,6 @@ void frame_grab_client(ObFrame *self) /* map the client so it maps when the frame does */ XMapWindow(ob_display, self->client->window); - /* adjust the frame to the client's size */ - frame_adjust_area(self, FALSE, TRUE, FALSE); - /* set all the windows for the frame in the window_map */ g_hash_table_insert(window_map, &self->window, self->client); g_hash_table_insert(window_map, &self->plate, self->client); diff --git a/tests/noresize.c b/tests/noresize.c index fa920bf1..ed32937a 100644 --- a/tests/noresize.c +++ b/tests/noresize.c @@ -40,7 +40,7 @@ int main () { xswamask = CWWinGravity; win = XCreateWindow(display, RootWindow(display, 0), - x, y, w, h, 10, CopyFromParent, CopyFromParent, + x, y, w, h, 0, CopyFromParent, CopyFromParent, CopyFromParent, xswamask, &xswa); XSetWindowBackground(display,win,WhitePixel(display,0)); @@ -52,10 +52,13 @@ int main () { size.min_height = h; XSetWMNormalHints(display, win, &size); + XSelectInput(display, win, ExposureMask | StructureNotifyMask); + XMapWindow(display, win); XFlush(display); - XSelectInput(display, win, ExposureMask | StructureNotifyMask); + XMoveWindow(display, win, 10, 10); + XMoveWindow(display, win, 10, 10); while (1) { XNextEvent(display, &report);