X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=6b8635be8eaa9d69c40930f6dca485ce4cf18e01;hb=55d2916c1e24e021d9b9692d2373dc4afff4c5c2;hp=fceac8755836690df529d53ea88138816ec84013;hpb=8446e50b7a6af13f2e06b8bdb2784ce2cb11ce5e;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index fceac875..6b8635be 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -374,7 +374,6 @@ void client_manage(Window window) self->window, newx, newy, self->area.width, self->area.height); client_apply_startup_state(self, newx, newy); - keyboard_grab_for_client(self, TRUE); mouse_grab_for_client(self, TRUE); if (activate) { @@ -385,10 +384,18 @@ void client_manage(Window window) ob_debug("Want to focus new window 0x%x with time %u (last time %u)\n", self->window, self->user_time, last_time); - /* If a nothing at all, or a parent was focused, then focus this + /* if it's on another desktop */ + if (!(self->desktop == screen_desktop || self->desktop == DESKTOP_ALL) + && /* the timestamp is from before you changed desktops */ + self->user_time && screen_desktop_user_time && + !event_time_after(self->user_time, screen_desktop_user_time)) + { + activate = FALSE; + } + /* If nothing is focused, or a parent was focused, then focus this always */ - if (!focus_client || client_search_focus_parent(self) != NULL) + else if (!focus_client || client_search_focus_parent(self) != NULL) activate = TRUE; else { @@ -476,13 +483,9 @@ void client_unmanage(ObClient *self) /* flush to send the hide to the server quickly */ XFlush(ob_display); - if (focus_client == self) { - /* ignore enter events from the unmap so it doesnt mess with the focus - */ - event_ignore_queued_enters(); - } + /* ignore enter events from the unmap so it doesnt mess with the focus */ + event_ignore_queued_enters(); - keyboard_grab_for_client(self, FALSE); mouse_grab_for_client(self, FALSE); /* remove the window from our save set */ @@ -490,9 +493,24 @@ void client_unmanage(ObClient *self) /* update the focus lists */ focus_order_remove(self); - /* don't leave an invalid focus_client */ - if (self == focus_client) - focus_client = NULL; + if (client_focused(self)) { + /* we have to fall back here because we might not get a focus out. + 1. we need to xselectinput off the window before we unmap it because + otherwise we end up getting unmapnotifies we don't want and they + can mess up mapping it again quickly + 2. this means that if we unmanage from a synthetic unmapnotify, we + are the ones unmapped it, and causing the focusout. so we won't + get the focusout event. + 3. we can't handle focusin events on the root window because they + come from all screens, so the focus change gets lost + + if this ever gets removed in the future MAKE SURE to replace it + with: + /- don't leave an invalid focus_client -/ + focus_client = NULL; + */ + focus_fallback(FALSE); + } client_list = g_list_remove(client_list, self); stacking_remove(self); @@ -736,8 +754,10 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h, Rect *a; gint ox = *x, oy = *y; - frame_client_gravity(self->frame, x, y); /* get where the frame - would be */ + /* XXX figure out if it is on screen now, and be rude if it is */ + + /* get where the frame would be */ + frame_client_gravity(self->frame, x, y, w, h); /* XXX watch for xinerama dead areas */ /* This makes sure windows aren't entirely outside of the screen so you @@ -786,8 +806,8 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h, } } - frame_frame_gravity(self->frame, x, y); /* get where the client - should be */ + /* get where the client should be */ + frame_frame_gravity(self->frame, x, y, w, h); return ox != *x || oy != *y; } @@ -1131,7 +1151,8 @@ void client_update_transient_for(ObClient *self) /* remove from old parents */ for (it = self->group->members; it; it = g_slist_next(it)) { ObClient *c = it->data; - if (c != self && !c->transient_for) + if (c != self && (!c->transient_for || + c->transient_for != OB_TRAN_GROUP)) c->transients = g_slist_remove(c->transients, self); } } else if (self->transient_for != NULL) { /* transient of window */ @@ -1146,7 +1167,8 @@ void client_update_transient_for(ObClient *self) /* add to new parents */ for (it = self->group->members; it; it = g_slist_next(it)) { ObClient *c = it->data; - if (c != self && !c->transient_for) + if (c != self && (!c->transient_for || + c->transient_for != OB_TRAN_GROUP)) c->transients = g_slist_append(c->transients, self); } @@ -1331,9 +1353,9 @@ void client_update_normal_hints(ObClient *self) if (self->frame && self->gravity != oldgravity) { /* move our idea of the client's position based on its new gravity */ - self->area.x = self->frame->area.x; - self->area.y = self->frame->area.y; - frame_frame_gravity(self->frame, &self->area.x, &self->area.y); + client_convert_gravity(self, oldgravity, + &self->area.x, &self->area.y, + self->area.width, self->area.height); } } @@ -1552,7 +1574,7 @@ void client_reconfigure(ObClient *self) /* by making this pass FALSE for user, we avoid the emacs event storm where every configurenotify causes an update in its normal hints, i think this is generally what we want anyways... */ - client_configure(self, OB_CORNER_TOPLEFT, self->area.x, self->area.y, + client_configure(self, self->area.x, self->area.y, self->area.width, self->area.height, FALSE, TRUE); } @@ -1850,7 +1872,7 @@ void client_update_icons(ObClient *self) RrPixel32 *icon = ob_rr_theme->def_win_icon; gulong *data; - data = g_new(guint32, 48*48+2); + data = g_new(gulong, 48*48+2); data[0] = data[1] = 48; for (i = 0; i < 48*48; ++i) data[i+2] = (((icon[i] >> RrDefaultAlphaOffset) & 0xff) << 24) + @@ -2205,8 +2227,21 @@ static void client_apply_startup_state(ObClient *self, gint x, gint y) */ } -void client_try_configure(ObClient *self, ObCorner anchor, - gint *x, gint *y, gint *w, gint *h, +void client_convert_gravity(ObClient *self, gint gravity, gint *x, gint *y, + gint w, gint h) +{ + gint oldg = self->gravity; + + /* get the frame's position from the requested stuff */ + self->gravity = gravity; + frame_client_gravity(self->frame, x, y, w, h); + self->gravity = oldg; + + /* get the client's position in its true gravity from that */ + frame_frame_gravity(self->frame, x, y, w, h); +} + +void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, gint *logicalw, gint *logicalh, gboolean user) { @@ -2301,7 +2336,7 @@ void client_try_configure(ObClient *self, ObCorner anchor, } /* gets the frame's position */ - frame_client_gravity(self->frame, x, y); + frame_client_gravity(self->frame, x, y, *w, *h); /* these positions are frame positions, not client positions */ @@ -2342,7 +2377,7 @@ void client_try_configure(ObClient *self, ObCorner anchor, } /* gets the client's position */ - frame_frame_gravity(self->frame, x, y); + frame_frame_gravity(self->frame, x, y, *w, *h); /* these override the above states! if you cant move you can't move! */ if (user) { @@ -2358,26 +2393,10 @@ void client_try_configure(ObClient *self, ObCorner anchor, g_assert(*w > 0); g_assert(*h > 0); - - switch (anchor) { - case OB_CORNER_TOPLEFT: - break; - case OB_CORNER_TOPRIGHT: - *x -= *w - self->area.width; - break; - case OB_CORNER_BOTTOMLEFT: - *y -= *h - self->area.height; - break; - case OB_CORNER_BOTTOMRIGHT: - *x -= *w - self->area.width; - *y -= *h - self->area.height; - break; - } } -void client_configure_full(ObClient *self, ObCorner anchor, - 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) { @@ -2389,8 +2408,7 @@ void client_configure_full(ObClient *self, ObCorner anchor, gint logicalw, logicalh; /* find the new x, y, width, and height (and logical size) */ - client_try_configure(self, anchor, &x, &y, &w, &h, - &logicalw, &logicalh, user); + client_try_configure(self, &x, &y, &w, &h, &logicalw, &logicalh, user); /* set the logical size if things changed */ if (!(w == self->area.width && h == self->area.height)) @@ -2412,10 +2430,8 @@ void client_configure_full(ObClient *self, ObCorner anchor, (resized && config_resize_redraw)))); /* if the client is enlarging, then resize the client before the frame */ - if (send_resize_client && user && (w > oldw || h > oldh)) { + if (send_resize_client && user && (w > oldw || h > oldh)) XResizeWindow(ob_display, self->window, MAX(w, oldw), MAX(h, oldh)); - frame_adjust_client_area(self->frame); - } /* find the frame's dimensions and move/resize it */ if (self->decorations != fdecor || self->max_horz != fhorz) @@ -2461,10 +2477,8 @@ void client_configure_full(ObClient *self, ObCorner anchor, } /* if the client is shrinking, then resize the frame before the client */ - if (send_resize_client && (!user || (w <= oldw || h <= oldh))) { - frame_adjust_client_area(self->frame); + if (send_resize_client && (!user || (w <= oldw || h <= oldh))) XResizeWindow(ob_display, self->window, w, h); - } XFlush(ob_display); } @@ -3106,6 +3120,9 @@ void client_activate(ObClient *self, gboolean here, gboolean user) { client_hilite(self, TRUE); } else { + if (event_curtime != CurrentTime) + self->user_time = event_curtime; + /* if using focus_delay, stop the timer now so that focus doesn't go moving on us */ event_halt_focus_delay(); @@ -3235,7 +3252,7 @@ void client_set_undecorated(ObClient *self, gboolean undecorated) * since 125 of these are sent per second when moving the window (with * user = FALSE) i doubt it matters much. */ - client_configure(self, OB_CORNER_TOPLEFT, self->area.x, self->area.y, + client_configure(self, self->area.x, self->area.y, self->area.width, self->area.height, TRUE, TRUE); client_change_state(self); /* reflect this in the state hints */ }