X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=d65ce4a193c0711cb8c4ce49f49b294ad9c4c24f;hb=a07465f376b0a33270532501127ec812efe2c2b2;hp=d80ed2986736b17b296f47c4e61d22f33acae00b;hpb=99c6a00cf6cae461f45d8fd3e852a9479f3694bc;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index d80ed298..d65ce4a1 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -88,7 +88,8 @@ static void client_update_transient_tree(ObClient *self, gboolean oldgtran, gboolean newgtran, ObClient* oldparent, ObClient *newparent); -static void client_present(ObClient *self, gboolean here, gboolean raise); +static void client_present(ObClient *self, gboolean here, gboolean raise, + gboolean unshade); static GSList *client_search_all_top_parents_internal(ObClient *self, gboolean bylayer, ObStackingLayer layer); @@ -394,7 +395,7 @@ void client_manage(Window window) */ if (ob_state() == OB_STATE_RUNNING && (transient || - (!(self->sized & USSize) && + (!(self->sized & USSize || self->positioned & USPosition) && client_normal(self) && !self->session))) { @@ -544,7 +545,7 @@ void client_manage(Window window) if (activate) { gboolean stacked = client_restore_session_stacking(self); - client_present(self, FALSE, !stacked); + client_present(self, FALSE, !stacked, TRUE); } /* add to client list/map */ @@ -1808,24 +1809,6 @@ static void client_change_allowed_actions(ObClient *self) } } -void client_reconfigure(ObClient *self, gboolean force) -{ - gint x, y, w, h, lw, lh; - - RECT_TO_DIMS(self->area, x, y, w, h); - if (!force) - client_try_configure(self, &x, &y, &w, &h, &lw, &lh, FALSE); - if (force || !RECT_EQUAL_DIMS(self->area, x, y, w, h)) { - gulong ignore_start; - - ob_debug("Reconfiguring client x %d y %d w %d h %d\n", - x, y, w, h); - ignore_start = event_start_ignore_all_enters(); - client_configure(self, x, y, w, h, FALSE, TRUE); - event_end_ignore_all_enters(ignore_start); - } -} - void client_update_wmhints(ObClient *self) { XWMHints *hints; @@ -2102,8 +2085,11 @@ void client_update_icons(ObClient *self) /* set the default icon onto the window in theory, this could be a race, but if a window doesn't set an icon or removes it entirely, it's not very likely it is going to set one - right away afterwards */ - if (self->nicons == 0) { + right away afterwards + + if it has parents, then one of them will have an icon already + */ + if (self->nicons == 0 && !self->parents) { RrPixel32 *icon = ob_rr_theme->def_win_icon; gulong *data; @@ -2630,7 +2616,7 @@ static void client_apply_startup_state(ObClient *self, /* 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); + client_configure(self, x, y, w, h, FALSE, TRUE, FALSE); } /* set the desktop hint, to make sure that it always exists */ @@ -2873,11 +2859,11 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, void client_configure(ObClient *self, gint x, gint y, gint w, gint h, - gboolean user, gboolean final) + gboolean user, gboolean final, gboolean force_reply) { gint oldw, oldh; gboolean send_resize_client; - gboolean moved = FALSE, resized = FALSE; + gboolean moved = FALSE, resized = FALSE, rootmoved = FALSE; gboolean fmoved, fresized; guint fdecor = self->frame->decorations; gboolean fhorz = self->frame->max_horz; @@ -2926,34 +2912,49 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h, } /* adjust the frame */ - if (fmoved || fresized) + if (fmoved || fresized) { + gulong ignore_start; + if (!user) + ignore_start = event_start_ignore_all_enters(); + frame_adjust_area(self->frame, fmoved, fresized, FALSE); + if (!user) + event_end_ignore_all_enters(ignore_start); + } + + if (!user || final) { + gint oldrx = self->root_pos.x; + gint oldry = self->root_pos.y; + /* we have reset the client to 0 border width, so don't include + it in these coords */ + POINT_SET(self->root_pos, + self->frame->area.x + self->frame->size.left - + self->border_width, + self->frame->area.y + self->frame->size.top - + self->border_width); + if (self->root_pos.x != oldrx || self->root_pos.y != oldry) + rootmoved = TRUE; + } + /* 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. + in this case (if force_reply is true) 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 + maximize a window or something. 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)) + if ((!user && !resized && (rootmoved || force_reply)) || + (user && final && rootmoved)) { XEvent event; - /* we have reset the client to 0 border width, so don't include - it in these coords */ - POINT_SET(self->root_pos, - self->frame->area.x + self->frame->size.left - - self->border_width, - self->frame->area.y + self->frame->size.top - - self->border_width); - event.type = ConfigureNotify; event.xconfigure.display = ob_display; event.xconfigure.event = self->window; @@ -3263,7 +3264,8 @@ void client_set_desktop_recursive(ObClient *self, frame_adjust_state(self->frame); /* 'move' the window to the new desktop */ if (!donthide) - client_showhide(self); + client_hide(self); + client_show(self); /* raise if it was not already on the desktop */ if (old != DESKTOP_ALL && !dontraise) stacking_raise(CLIENT_AS_WINDOW(self)); @@ -3560,6 +3562,10 @@ gboolean client_focus(ObClient *self) "Focusing client \"%s\" (0x%x) at time %u\n", self->title, self->window, event_curtime); + /* if using focus_delay, stop the timer now so that focus doesn't + go moving on us */ + event_halt_focus_delay(); + /* if there is a grab going on, then we need to cancel it. if we move focus during the grab, applications will get NotifyWhileGrabbed events and ignore them ! @@ -3600,17 +3606,9 @@ gboolean client_focus(ObClient *self) return !xerror_occured; } -/*! Present the client to the user. - @param raise If the client should be raised or not. You should only set - raise to false if you don't care if the window is completely - hidden. -*/ -static void client_present(ObClient *self, gboolean here, gboolean raise) +static void client_present(ObClient *self, gboolean here, gboolean raise, + gboolean unshade) { - /* if using focus_delay, stop the timer now so that focus doesn't - go moving on us */ - event_halt_focus_delay(); - if (client_normal(self) && screen_showing_desktop) screen_show_desktop(FALSE, self); if (self->iconic) @@ -3626,7 +3624,7 @@ static void client_present(ObClient *self, gboolean here, gboolean raise) /* if its not visible for other reasons, then don't mess with it */ return; - if (self->shaded) + if (self->shaded && unshade) client_shade(self, FALSE); if (raise) stacking_raise(CLIENT_AS_WINDOW(self)); @@ -3634,7 +3632,8 @@ static void client_present(ObClient *self, gboolean here, gboolean raise) client_focus(self); } -void client_activate(ObClient *self, gboolean here, gboolean user) +void client_activate(ObClient *self, gboolean here, gboolean raise, + gboolean unshade, gboolean user) { guint32 last_time = focus_client ? focus_client->user_time : CurrentTime; gboolean allow = FALSE; @@ -3660,7 +3659,7 @@ void client_activate(ObClient *self, gboolean here, gboolean user) (user ? "user" : "application"), allow); if (allow) - client_present(self, here, TRUE); + client_present(self, here, raise, unshade); else /* don't focus it but tell the user it wants attention */ client_hilite(self, TRUE); @@ -4082,3 +4081,30 @@ gboolean client_has_group_siblings(ObClient *self) { return self->group && self->group->members->next; } + +ObClientIcon *client_thumbnail(ObClient *self, gint wantw, gint wanth) +{ + ObClientIcon *ret; + RrPixel32 *data; + gint w, h; + + if (!self->frame->pixmap) return NULL; + if (!RrPixmapToRGBA(ob_rr_inst, self->frame->pixmap, None, &w, &h, &data)) + return NULL; + + /* resize the thumbnail (within aspect ratio) to the given sizes */ + + ret = g_new(ObClientIcon, 1); + ret->data = data; + ret->width = w; + ret->height = h; + return ret; +} + +void clienticon_free(ObClientIcon *ci) +{ + if (ci) { + g_free(ci->data); + g_free(ci); + } +}