X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=474789ce40b066d7f737ec19e40a41a16f5be539;hb=3547fe26edf0671dbc0ec5b3a081f8629d13e4b9;hp=e1c814ce39c5d33138b40115a0475799a5171a44;hpb=a4150ae3d9ed61e5360c221c4be907560ba6531a;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index e1c814ce..474789ce 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -319,7 +319,7 @@ void client_manage(Window window) settings for other uses too. the returned settings is a shallow copy, that needs to be freed with g_free(). */ settings = client_get_settings_state(self); - /* the session should get the last say thought */ + /* the session should get the last say though */ client_restore_session_state(self); /* now we have all of the window's information so we can set this up */ @@ -349,10 +349,11 @@ void client_manage(Window window) client_search_focus_tree_full(self)) && /* this checks for focus=false for the window */ (!settings || settings->focus != 0) && - /* note the check against Type_Normal/Dialog, not client_normal(self), - which would also include other types. in this case we want more - strict rules for focus */ + /* note the check against type Normal/Dialog/Utility, + not client_normal(self), which would also include other types. + in this case we want more strict rules for focus */ (self->type == OB_CLIENT_TYPE_NORMAL || + self->type == OB_CLIENT_TYPE_UTILITY || self->type == OB_CLIENT_TYPE_DIALOG)) { activate = TRUE; @@ -2309,7 +2310,7 @@ static void client_change_wm_state(ObClient *self) static void client_change_state(ObClient *self) { - gulong netstate[11]; + gulong netstate[12]; guint num; num = 0; @@ -2565,6 +2566,8 @@ static void client_apply_startup_state(ObClient *self, gboolean demands_attention = self->demands_attention; gboolean max_horz = self->max_horz; gboolean max_vert = self->max_vert; + Rect oldarea; + gint l; /* turn them all off in the client, so they won't affect the window being placed */ @@ -2580,10 +2583,12 @@ static void client_apply_startup_state(ObClient *self, do this before applying the states so they have the correct pre-max/pre-fullscreen values */ - client_configure(self, x, y, w, h, FALSE, TRUE); + client_try_configure(self, &x, &y, &w, &h, &l, &l, FALSE); ob_debug("placed window 0x%x at %d, %d with size %d x %d\n", self->window, self->area.x, self->area.y, self->area.width, self->area.height); + oldarea = self->area; /* save the area */ + RECT_SET(self->area, x, y, w, h); /* put where it should be for the premax stuff */ /* apply the states. these are in a carefully crafted order.. */ @@ -2605,6 +2610,12 @@ static void client_apply_startup_state(ObClient *self, else if (max_horz) client_maximize(self, TRUE, 1); + /* if the window hasn't been configured yet, then do so now */ + if (!fullscreen && !max_vert && !max_horz) { + self->area = oldarea; + client_configure(self, x, y, w, h, FALSE, TRUE); + } + /* set the desktop hint, to make sure that it always exists */ PROP_SET32(self->window, net_wm_desktop, cardinal, self->desktop); @@ -2850,8 +2861,8 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h, SIZE_SET(self->logical_size, logicalw, logicalh); /* figure out if we moved or resized or what */ - moved = x != self->area.x || y != self->area.y; - resized = w != self->area.width || h != self->area.height; + moved = (x != self->area.x || y != self->area.y); + resized = (w != self->area.width || h != self->area.height); oldw = self->area.width; oldh = self->area.height; @@ -2866,7 +2877,9 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h, /* if the client is enlarging, then resize the client before the frame */ if (send_resize_client && (w > oldw || h > oldh)) { - XResizeWindow(ob_display, self->window, MAX(w, oldw), MAX(h, oldh)); + XMoveResizeWindow(ob_display, self->window, + self->frame->size.left, self->frame->size.top, + MAX(w, oldw), MAX(h, oldh)); frame_adjust_client_area(self->frame); } @@ -2885,7 +2898,20 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h, if (fmoved || fresized) frame_adjust_area(self->frame, fmoved, fresized, FALSE); - if ((!user || (user && final)) && !resized) + /* This is kinda tricky and should not be changed.. let me explain! + + When user = FALSE, then the request is coming from the application + itself, and we are more strict about when to send a synthetic + ConfigureNotify. We strictly follow the rules of the ICCCM sec 4.1.5 + in this case. + + When user = TRUE, then the request is coming from "us", like when we + maximize a window or sometihng. In this case we are more lenient. We + used to follow the same rules as above, but _Java_ Swing can't handle + this. So just to appease Swing, when user = TRUE, we always send + a synthetic ConfigureNotify to give the window its root coordinates. + */ + if ((!user && !resized) || (user && final)) { XEvent event; @@ -2917,10 +2943,15 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h, FALSE, StructureNotifyMask, &event); } - /* if the client is shrinking, then resize the frame before the client */ - if (send_resize_client && (w <= oldw && h <= oldh)) { + /* if the client is shrinking, then resize the frame before the client. + + both of these resize sections may run, because the top one only resizes + in the direction that is growing + */ + if (send_resize_client && (w <= oldw || h <= oldh)) { frame_adjust_client_area(self->frame); - XResizeWindow(ob_display, self->window, w, h); + XMoveResizeWindow(ob_display, self->window, + self->frame->size.left, self->frame->size.top, w, h); } XFlush(ob_display); @@ -3215,8 +3246,7 @@ void client_set_desktop_recursive(ObClient *self, client_set_desktop_recursive(it->data, target, donthide); } -void client_set_desktop(ObClient *self, guint target, - gboolean donthide) +void client_set_desktop(ObClient *self, guint target, gboolean donthide) { self = client_search_top_normal_parent(self); client_set_desktop_recursive(self, target, donthide); @@ -3605,29 +3635,35 @@ void client_activate(ObClient *self, gboolean here, gboolean user) static void client_bring_windows_recursive(ObClient *self, guint desktop, gboolean helpers, - gboolean modals) + gboolean modals, + gboolean iconic) { GSList *it; for (it = self->transients; it; it = g_slist_next(it)) - client_bring_windows_recursive(it->data, desktop, helpers, modals); + client_bring_windows_recursive(it->data, desktop, + helpers, modals, iconic); if (((helpers && client_helper(self)) || - (modals && self->modal))&& - self->desktop != desktop && self->desktop != DESKTOP_ALL) + (modals && self->modal)) && + ((self->desktop != desktop && self->desktop != DESKTOP_ALL) || + (iconic && self->iconic))) { - client_set_desktop(self, desktop, FALSE); + if (iconic && self->iconic) + client_iconify(self, FALSE, TRUE, FALSE); + else + client_set_desktop(self, desktop, FALSE); } } void client_bring_helper_windows(ObClient *self) { - client_bring_windows_recursive(self, self->desktop, TRUE, FALSE); + client_bring_windows_recursive(self, self->desktop, TRUE, FALSE, FALSE); } void client_bring_modal_windows(ObClient *self) { - client_bring_windows_recursive(self, self->desktop, FALSE, TRUE); + client_bring_windows_recursive(self, self->desktop, FALSE, TRUE, TRUE); } gboolean client_focused(ObClient *self)