X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=c8d87ab4516fbe5ae8ffeabb48def3e4f9bbce92;hb=1aa0bc66eb45ba466d1d071d0e6c13631331e091;hp=2361f9379de603599af50924ea5d1859e7058818;hpb=4c1641bfc704f17df6e0acb8bdeb20e877b377ad;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 2361f937..c8d87ab4 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -1,3 +1,4 @@ +#include "debug.h" #include "client.h" #include "dock.h" #include "xerror.h" @@ -216,7 +217,7 @@ void client_manage(Window window) XFree(wmhint); } - g_message("Managing window: %lx", window); + ob_debug("Managing window: %lx\n", window); /* choose the events we want to receive on the CLIENT window */ attrib_set.event_mask = CLIENT_EVENTMASK; @@ -248,13 +249,11 @@ void client_manage(Window window) grab_server(FALSE); - /* add to client list/map */ - client_list = g_list_append(client_list, self); - g_hash_table_insert(window_map, &self->window, self); - /* update the focus lists */ focus_order_add_new(self); + stacking_add(CLIENT_AS_WINDOW(self)); + /* focus the new window? */ if (ob_state() != OB_STATE_STARTING && config_focus_new && /* note the check against Type_Normal/Dialog, not client_normal(self), @@ -263,14 +262,10 @@ void client_manage(Window window) (self->type == OB_CLIENT_TYPE_NORMAL || self->type == OB_CLIENT_TYPE_DIALOG)) { - if (self->desktop != screen_desktop) - { + if (self->desktop != screen_desktop) { /* activate the window */ - stacking_add(CLIENT_AS_WINDOW(self)); activate = TRUE; - } - else - { + } else { gboolean group_foc = FALSE; if (self->group) { @@ -293,25 +288,15 @@ void client_manage(Window window) !client_normal(focus_client)) { /* activate the window */ - stacking_add(CLIENT_AS_WINDOW(self)); activate = TRUE; } - else - { - /* try to not get in the way */ - stacking_add_nonintrusive(CLIENT_AS_WINDOW(self)); - } } } - else - { - stacking_add(CLIENT_AS_WINDOW(self)); - } dispatch_client(Event_Client_New, self, 0, 0); /* make sure the window is visible */ - client_move_onscreen(self); + client_move_onscreen(self, TRUE); screen_update_areas(); @@ -324,12 +309,21 @@ void client_manage(Window window) but do focus it. */ if (activate) client_focus(self); + /* client_activate does this but we aret using it so we have to do it + here as well */ + if (screen_showing_desktop) + screen_show_desktop(FALSE); + /* update the list hints */ client_set_list(); dispatch_client(Event_Client_Mapped, self, 0, 0); - g_message("Managed window 0x%lx (%s)", window, self->class); + /* add to client list/map */ + client_list = g_list_append(client_list, self); + g_hash_table_insert(window_map, &self->window, self); + + ob_debug("Managed window 0x%lx (%s)\n", window, self->class); } void client_unmanage_all() @@ -350,7 +344,7 @@ void client_unmanage(ObClient *self) guint j; GSList *it; - g_message("Unmanaging window: %lx (%s)", self->window, self->class); + ob_debug("Unmanaging window: %lx (%s)\n", self->window, self->class); dispatch_client(Event_Client_Destroy, self, 0, 0); g_assert(self != NULL); @@ -431,8 +425,9 @@ void client_unmanage(ObClient *self) if (ob_state() != OB_STATE_EXITING) { /* these values should not be persisted across a window unmapping/mapping */ - prop_erase(self->window, prop_atoms.net_wm_desktop); - prop_erase(self->window, prop_atoms.net_wm_state); + PROP_ERASE(self->window, net_wm_desktop); + PROP_ERASE(self->window, net_wm_state); + PROP_ERASE(self->window, wm_state); } else { /* if we're left in an iconic state, the client wont be mapped. this is bad, since we will no longer be managing the window on restart */ @@ -441,7 +436,7 @@ void client_unmanage(ObClient *self) } - g_message("Unmanaged window 0x%lx", self->window); + ob_debug("Unmanaged window 0x%lx\n", self->window); /* free all data allocated in the client struct */ g_slist_free(self->transients); @@ -460,27 +455,61 @@ void client_unmanage(ObClient *self) client_set_list(); } -void client_move_onscreen(ObClient *self) +void client_move_onscreen(ObClient *self, gboolean rude) +{ + int x = self->area.x; + int y = self->area.y; + if (client_find_onscreen(self, &x, &y, + self->area.width, self->area.height, rude)) { + client_configure(self, OB_CORNER_TOPLEFT, x, y, + self->area.width, self->area.height, + TRUE, TRUE); + } +} + +gboolean client_find_onscreen(ObClient *self, int *x, int *y, int w, int h, + gboolean rude) { Rect *a; - int x = self->frame->area.x, y = self->frame->area.y; + int ox = *x, oy = *y; + + frame_client_gravity(self->frame, x, y); /* get where the frame + would be */ /* XXX watch for xinerama dead areas */ + a = screen_area(self->desktop); - if (x >= a->x + a->width - 1) - x = a->x + a->width - self->frame->area.width; - if (y >= a->y + a->height - 1) - y = a->y + a->height - self->frame->area.height; - if (x + self->frame->area.width - 1 < a->x) - x = a->x; - if (y + self->frame->area.height - 1< a->y) - y = a->y; - - frame_frame_gravity(self->frame, &x, &y); /* get where the client - should be */ - client_configure(self, OB_CORNER_TOPLEFT, x, y, - self->area.width, self->area.height, - TRUE, TRUE); + if (!self->strut.right && *x >= a->x + a->width - 1) + *x = a->x + a->width - self->frame->area.width; + if (!self->strut.bottom && *y >= a->y + a->height - 1) + *y = a->y + a->height - self->frame->area.height; + if (!self->strut.left && *x + self->frame->area.width - 1 < a->x) + *x = a->x; + if (!self->strut.top && *y + self->frame->area.height - 1 < a->y) + *y = a->y; + + if (rude) { + /* this is my MOZILLA BITCHSLAP. oh ya it fucking feels good. + Java can suck it too. */ + + /* dont let windows map/move into the strut unless they + are bigger than the available area */ + if (w <= a->width) { + if (!self->strut.left && *x < a->x) *x = a->x; + if (!self->strut.right && *x + w > a->x + a->width) + *x = a->x + a->width - w; + } + if (h <= a->height) { + if (!self->strut.top && *y < a->y) *y = a->y; + if (!self->strut.bottom && *y + h > a->y + a->height) + *y = a->y + a->height - h; + } + } + + frame_frame_gravity(self->frame, x, y); /* get where the client + should be */ + + return ox != *x || oy != *y; } static void client_toggle_border(ObClient *self, gboolean show) @@ -897,7 +926,7 @@ void client_update_normal_hints(ObClient *self) /* get the hints from the window */ if (XGetWMNormalHints(ob_display, self->window, &size, &ret)) { - self->positioned = !!(size.flags & (PPosition|USPosition)); + self->positioned = !!(size.flags & (PPosition|USPosition)); if (size.flags & PWinGravity) { self->gravity = size.win_gravity; @@ -1105,7 +1134,6 @@ static void client_change_allowed_actions(ObClient *self) else self->shaded = FALSE; } if (!(self->functions & OB_CLIENT_FUNC_ICONIFY) && self->iconic) { - g_message("UNSETTING ICONIC"); if (self->frame) client_iconify(self, FALSE, TRUE); else self->iconic = FALSE; } @@ -1198,8 +1226,8 @@ void client_update_wmhints(ObClient *self) if (ur != self->urgent) { self->urgent = ur; - g_message("Urgent Hint for 0x%lx: %s", self->window, - ur ? "ON" : "OFF"); + ob_debug("Urgent Hint for 0x%lx: %s\n", self->window, + ur ? "ON" : "OFF"); /* fire the urgent callback if we're mapped, otherwise, wait until after we're mapped */ if (self->frame) @@ -1626,9 +1654,10 @@ static void client_apply_startup_state(ObClient *self) */ } -void client_configure(ObClient *self, ObCorner anchor, - int x, int y, int w, int h, - gboolean user, gboolean final) +void client_configure_full(ObClient *self, ObCorner anchor, + int x, int y, int w, int h, + gboolean user, gboolean final, + gboolean force_reply) { gboolean moved = FALSE, resized = FALSE; @@ -1820,20 +1849,19 @@ void client_configure(ObClient *self, ObCorner anchor, if (moved || resized) frame_adjust_area(self->frame, moved, resized); - /* If you send this and the client hasn't changed you end up with buggy - clients (emacs) freaking out, cuz they send back a configure every - time they receive this event, which resends them this event... etc. - */ - if ((!user && moved) || (user && final)) { + if (force_reply || (!resized && ((!user && moved) || (user && final)))) + { XEvent event; event.type = ConfigureNotify; event.xconfigure.display = ob_display; event.xconfigure.event = self->window; event.xconfigure.window = self->window; - + /* root window real coords */ - event.xconfigure.x = self->frame->area.x + self->frame->size.left; - event.xconfigure.y = self->frame->area.y + self->frame->size.top; + event.xconfigure.x = self->frame->area.x + self->frame->size.left - + self->border_width; + event.xconfigure.y = self->frame->area.y + self->frame->size.top - + self->border_width; event.xconfigure.width = w; event.xconfigure.height = h; @@ -1912,8 +1940,8 @@ static void client_iconify_recursive(ObClient *self, if (self->iconic != iconic) { - g_message("%sconifying window: 0x%lx", (iconic ? "I" : "Uni"), - self->window); + ob_debug("%sconifying window: 0x%lx\n", (iconic ? "I" : "Uni"), + self->window); self->iconic = iconic; @@ -2133,7 +2161,7 @@ void client_set_desktop_recursive(ObClient *self, if (target != self->desktop) { - g_message("Setting desktop %u", target+1); + ob_debug("Setting desktop %u\n", target+1); g_assert(target < screen_num_desktops || target == DESKTOP_ALL); @@ -2423,9 +2451,9 @@ gboolean client_focus(ObClient *self) } #ifdef DEBUG_FOCUS - g_message("%sively focusing %lx at %d", (self->can_focus ? "act" : "pass"), - self->window, (int) - event_lasttime); + ob_debug("%sively focusing %lx at %d\n", + (self->can_focus ? "act" : "pass"), + self->window, (int) event_lasttime); #endif /* Cause the FocusIn to come back to us. Important for desktop switches, @@ -2439,7 +2467,7 @@ void client_unfocus(ObClient *self) { g_assert(focus_client == self); #ifdef DEBUG_FOCUS - g_message("client_unfocus for %lx", self->window); + ob_debug("client_unfocus for %lx\n", self->window); #endif focus_fallback(OB_FOCUS_FALLBACK_UNFOCUSING); } @@ -2642,3 +2670,16 @@ ObClient *client_search_top_transient(ObClient *self) return self; } + +ObClient *client_search_transient(ObClient *self, ObClient *search) +{ + GSList *sit; + + for (sit = self->transients; sit; sit = g_slist_next(sit)) { + if (sit->data == search) + return search; + if (client_search_transient(sit->data, search)) + return search; + } + return NULL; +}