X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=3e069464218c5ba1bfcb7b724b753bcc322dfff0;hb=5fb30e4488f8d979967d52fa5cfb7bec6ff1d5f4;hp=1a0d2531c23423f63bd324eef262c76654a8cf23;hpb=5f7ffb00ba0050de28e915f6dcbd711b03eec938;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 1a0d2531..3e069464 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -78,6 +78,7 @@ static void client_apply_startup_state(ObClient *self, gint x, gint y); static void client_restore_session_state(ObClient *self); static void client_restore_session_stacking(ObClient *self); static ObAppSettings *client_get_settings_state(ObClient *self); +static void client_unfocus(ObClient *self); void client_startup(gboolean reconfig) { @@ -219,13 +220,14 @@ void client_manage(Window window) grab_server(TRUE); - /* check if it has already been unmapped by the time we started mapping + /* check if it has already been unmapped by the time we started mapping. the grab does a sync so we don't have to here */ if (XCheckTypedWindowEvent(ob_display, window, DestroyNotify, &e) || XCheckTypedWindowEvent(ob_display, window, UnmapNotify, &e)) { XPutBackEvent(ob_display, &e); + ob_debug("Trying to manage unmapped window. Aborting that.\n"); grab_server(FALSE); return; /* don't manage it */ } @@ -267,7 +269,6 @@ void client_manage(Window window) self->window = window; /* non-zero defaults */ - self->title_count = 1; self->wmstate = WithdrawnState; /* make sure it gets updated first time */ self->layer = -1; self->desktop = screen_num_desktops; /* always an invalid value */ @@ -393,6 +394,8 @@ void client_manage(Window window) won't be all wacko!! also, this moves the window to the position where it has been placed */ + ob_debug("placing window 0x%x at %d, %d with size %d x %d\n", + self->window, newx, newy, self->area.width, self->area.height); client_apply_startup_state(self, newx, newy); keyboard_grab_for_client(self, TRUE); @@ -411,12 +414,15 @@ void client_manage(Window window) else { /* If time stamp is old, don't steal focus */ - if (self->user_time && self->user_time < client_last_user_time) + if (self->user_time && + !event_time_after(self->user_time, client_last_user_time)) + { activate = FALSE; + } /* Don't steal focus from globally active clients. I stole this idea from KWin. It seems nice. */ - if (!focus_client->can_focus && focus_client->focus_notify) + if (!(focus_client->can_focus || focus_client->focus_notify)) activate = FALSE; } @@ -498,29 +504,44 @@ void client_unmanage(ObClient *self) g_assert(self != NULL); - keyboard_grab_for_client(self, FALSE); - mouse_grab_for_client(self, FALSE); + /* update the focus lists */ + focus_order_remove(self); + + if (focus_client == self) { + XEvent e; + + /* focus the last focused window on the desktop, and ignore enter + events from the unmap so it doesnt mess with the focus */ + while (XCheckTypedEvent(ob_display, EnterNotify, &e)); + /* remove these flags so we don't end up getting focused in the + fallback! */ + self->can_focus = FALSE; + self->focus_notify = FALSE; + self->modal = FALSE; + client_unfocus(self); + } /* potentially fix focusLast */ if (config_focus_last) grab_pointer(TRUE, OB_CURSOR_NONE); + frame_hide(self->frame); + XFlush(ob_display); + + keyboard_grab_for_client(self, FALSE); + mouse_grab_for_client(self, FALSE); + /* remove the window from our save set */ XChangeSaveSet(ob_display, self->window, SetModeDelete); /* we dont want events no more */ XSelectInput(ob_display, self->window, NoEventMask); - frame_hide(self->frame); - client_list = g_list_remove(client_list, self); stacking_remove(self); g_hash_table_remove(window_map, &self->window); - /* update the focus lists */ - focus_order_remove(self); - - /* once the client is out of the list, update the struts to remove it's + /* once the client is out of the list, update the struts to remove its influence */ if (STRUT_EXISTS(self->strut)) screen_update_areas(); @@ -529,20 +550,6 @@ void client_unmanage(ObClient *self) Destructor *d = it->data; d->func(self, d->data); } - - if (focus_client == self) { - XEvent e; - - /* focus the last focused window on the desktop, and ignore enter - events from the unmap so it doesnt mess with the focus */ - while (XCheckTypedEvent(ob_display, EnterNotify, &e)); - /* remove these flags so we don't end up getting focused in the - fallback! */ - self->can_focus = FALSE; - self->focus_notify = FALSE; - self->modal = FALSE; - client_unfocus(self); - } /* tell our parent(s) that we're gone */ if (self->transient_for == OB_TRAN_GROUP) { /* transient of group */ @@ -1642,108 +1649,44 @@ void client_update_wmhints(ObClient *self) void client_update_title(ObClient *self) { - GList *it; - guint32 nums; - guint i; gchar *data = NULL; - gboolean read_title; - gchar *old_title; - old_title = self->title; + g_free(self->title); /* try netwm */ if (!PROP_GETS(self->window, net_wm_name, utf8, &data)) { /* try old x stuff */ if (!(PROP_GETS(self->window, wm_name, locale, &data) || PROP_GETS(self->window, wm_name, utf8, &data))) { - // http://developer.gnome.org/projects/gup/hig/draft_hig_new/windows-alert.html if (self->transient) { + /* + GNOME alert windows are not given titles: + http://developer.gnome.org/projects/gup/hig/draft_hig_new/windows-alert.html + */ data = g_strdup(""); - goto no_number; } else data = g_strdup("Unnamed Window"); } } - if (config_title_number) { - - /* did the title change? then reset the title_count */ - if (old_title && 0 != strncmp(old_title, data, strlen(data))) - self->title_count = 1; - - /* look for duplicates and append a number */ - nums = 0; - for (it = client_list; it; it = g_list_next(it)) - if (it->data != self) { - ObClient *c = it->data; - - if (c->title_count == 1) { - if (!strcmp(c->title, data)) - nums |= 1 << c->title_count; - } else { - size_t len; - gchar *end; - - /* find the beginning of our " - [%u]", this relies on - that syntax being used */ - end = strrchr(c->title, '-') - 1; - len = end - c->title; - if (!strncmp(c->title, data, len)) - nums |= 1 << c->title_count; - } - } - /* find first free number */ - for (i = 1; i <= 32; ++i) - if (!(nums & (1 << i))) { - if (self->title_count == 1 || i == 1) - self->title_count = i; - break; - } - /* dont display the number for the first window */ - if (self->title_count > 1) { - gchar *ndata; - ndata = g_strdup_printf("%s - [%u]", data, self->title_count); - g_free(data); - data = ndata; - } - } else - self->title_count = 1; - -no_number: PROP_SETS(self->window, net_wm_visible_name, data); self->title = data; if (self->frame) frame_adjust_title(self->frame); - g_free(old_title); - /* update the icon title */ data = NULL; g_free(self->icon_title); - read_title = TRUE; /* try netwm */ if (!PROP_GETS(self->window, net_wm_icon_name, utf8, &data)) /* try old x stuff */ - if (!(PROP_GETS(self->window, wm_icon_name, locale, &data) - || PROP_GETS(self->window, wm_icon_name, utf8, &data))) { + if (!(PROP_GETS(self->window, wm_icon_name, locale, &data) || + PROP_GETS(self->window, wm_icon_name, utf8, &data))) data = g_strdup(self->title); - read_title = FALSE; - } - - /* append the title count, dont display the number for the first window. - * We don't need to check for config_title_number here since title_count - * is not set above 1 then. */ - if (read_title && self->title_count > 1) { - gchar *newdata; - newdata = g_strdup_printf("%s - [%u]", data, self->title_count); - g_free(data); - data = newdata; - } PROP_SETS(self->window, net_wm_visible_icon_name, data); - self->icon_title = data; } @@ -1925,7 +1868,10 @@ void client_update_user_time(ObClient *self, gboolean new_event) if (new_event) client_last_user_time = time; - /*ob_debug("window 0x%x user time %u\n", self->window, time);*/ + /* + ob_debug("window %s user time %u\n", self->title, time); + ob_debug("last user time %u\n", client_last_user_time); + */ } } @@ -2387,8 +2333,9 @@ void client_configure_full(ObClient *self, ObCorner anchor, client_try_configure(self, anchor, &x, &y, &w, &h, &logicalw, &logicalh, user); - /* set the logical size */ - SIZE_SET(self->logical_size, logicalw, logicalh); + /* set the logical size if things changed */ + if (!(w == self->area.width && h == self->area.height)) + 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; @@ -2514,10 +2461,10 @@ static void client_iconify_recursive(ObClient *self, ob_debug("%sconifying window: 0x%lx\n", (iconic ? "I" : "Uni"), self->window); - self->iconic = iconic; - if (iconic) { if (self->functions & OB_CLIENT_FUNC_ICONIFY) { + self->iconic = iconic; + /* update the focus lists.. iconic windows go to the bottom of the list, put the new iconic window at the 'top of the bottom'. */ @@ -2526,6 +2473,8 @@ static void client_iconify_recursive(ObClient *self, changed = TRUE; } } else { + self->iconic = iconic; + if (curdesk) client_set_desktop(self, screen_desktop, FALSE); @@ -3014,11 +2963,6 @@ gboolean client_focus(ObClient *self) /* choose the correct target */ self = client_focus_target(self); -#if 0 - if (!client_validate(self)) - return FALSE; -#endif - if (!client_can_focus(self)) { if (!self->frame->visible) { /* update the focus lists */ @@ -3030,14 +2974,7 @@ gboolean client_focus(ObClient *self) ob_debug("Focusing client \"%s\" at time %u\n", self->title, event_curtime); if (self->can_focus) { - /* RevertToPointerRoot causes much more headache than RevertToNone, so - I choose to use it always, hopefully to find errors quicker, if any - are left. (I hate X. I hate focus events.) - - Update: Changing this to RevertToNone fixed a bug with mozilla (bug - #799. So now it is RevertToNone again. - */ - XSetInputFocus(ob_display, self->window, RevertToNone, + XSetInputFocus(ob_display, self->window, RevertToPointerRoot, event_curtime); } @@ -3072,17 +3009,17 @@ gboolean client_focus(ObClient *self) /* Used when the current client is closed or otherwise hidden, focus_last will then prevent focus from going to the mouse pointer */ -void client_unfocus(ObClient *self) +static void client_unfocus(ObClient *self) { if (focus_client == self) { #ifdef DEBUG_FOCUS ob_debug("client_unfocus for %lx\n", self->window); #endif - focus_fallback(OB_FOCUS_FALLBACK_CLOSED); + focus_fallback(FALSE); } } -void client_activate(ObClient *self, gboolean here, gboolean user, Time time) +void client_activate(ObClient *self, gboolean here, gboolean user) { /* XXX do some stuff here if user is false to determine if we really want to activate it or not (a parent or group member is currently @@ -3090,11 +3027,13 @@ void client_activate(ObClient *self, gboolean here, gboolean user, Time time) */ ob_debug("Want to activate window 0x%x with time %u (last time %u), " "source=%s\n", - self->window, time, client_last_user_time, + self->window, event_curtime, client_last_user_time, (user ? "user" : "application")); - if (!user && time && time < client_last_user_time) + if (!user && event_curtime && + !event_time_after(event_curtime, client_last_user_time)) + { client_hilite(self, TRUE); - else { + } else { if (client_normal(self) && screen_showing_desktop) screen_show_desktop(FALSE); if (self->iconic)