X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=19b65f03719d976e1b7b2428ee8bcd17e58937de;hb=02dda1ef65dc71ec0b7f375c939c3d1a56ac7034;hp=5e1a78513992929a178fb871bfbffa0b89a1b3b2;hpb=97cbacd9e41ae2315434d6e83ce78502a881d54f;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 5e1a7851..19b65f03 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -277,7 +277,7 @@ void client_manage(Window window) self->wmstate = WithdrawnState; /* make sure it gets updated first time */ self->layer = -1; self->desktop = screen_num_desktops; /* always an invalid value */ - self->user_time = CurrentTime; + self->user_time = focus_client ? focus_client->user_time : CurrentTime; client_get_all(self); /* per-app settings override stuff, and return the settings for other @@ -347,8 +347,8 @@ void client_manage(Window window) /* make sure the window is visible. */ client_find_onscreen(self, &newx, &newy, - self->frame->area.width, - self->frame->area.height, + self->area.width, + self->area.height, /* non-normal clients has less rules, and windows that are being restored from a session do also. we can assume you want @@ -381,8 +381,10 @@ void client_manage(Window window) focus_client->user_time : CurrentTime; /* This is focus stealing prevention */ - ob_debug("Want to focus new window 0x%x with time %u (last time %u)\n", - self->window, self->user_time, last_time); + ob_debug_type(OB_DEBUG_FOCUS, + "Want to focus new window 0x%x with time %u " + "(last time %u)\n", + self->window, self->user_time, last_time); /* if it's on another desktop */ if (!(self->desktop == screen_desktop || self->desktop == DESKTOP_ALL) @@ -391,31 +393,38 @@ void client_manage(Window window) !event_time_after(self->user_time, screen_desktop_user_time)) { activate = FALSE; + ob_debug_type(OB_DEBUG_FOCUS, + "Not focusing the window because its on another " + "desktop\n"); } - /* If nothing is focused, or a parent was focused, then focus this - always - */ - else if (!focus_client || client_search_focus_parent(self) != NULL) - activate = TRUE; - else + /* If something is focused, and it's not our parent... */ + else if (focus_client && client_search_focus_parent(self) == NULL) { /* If time stamp is old, don't steal focus */ if (self->user_time && last_time && !event_time_after(self->user_time, last_time)) { activate = FALSE; + ob_debug_type(OB_DEBUG_FOCUS, + "Not focusing the window because the time is " + "too old\n"); } /* 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; + ob_debug_type(OB_DEBUG_FOCUS, + "Not focusing the window because a globally " + "active client has focus\n"); + } } if (!activate) { - ob_debug("Focus stealing prevention activated for %s with time %u " - "(last time %u)\n", - self->title, self->user_time, last_time); + ob_debug_type(OB_DEBUG_FOCUS, + "Focus stealing prevention activated for %s with " + "time %u (last time %u)\n", + self->title, self->user_time, last_time); /* if the client isn't focused, then hilite it so the user knows it is there */ client_hilite(self, TRUE); @@ -494,22 +503,8 @@ void client_unmanage(ObClient *self) /* update the focus lists */ focus_order_remove(self); 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); + /* don't leave an invalid focus_client */ + focus_client = NULL; } client_list = g_list_remove(client_list, self); @@ -742,8 +737,8 @@ void client_move_onscreen(ObClient *self, gboolean rude) gint x = self->area.x; gint y = self->area.y; if (client_find_onscreen(self, &x, &y, - self->frame->area.width, - self->frame->area.height, rude)) { + self->area.width, + self->area.height, rude)) { client_move(self, x, y); } } @@ -1207,6 +1202,8 @@ void client_update_transient_for(ObClient *self) c->transients = g_slist_append(c->transients, self); } +/* XXX can i remove this ?? */ + /* remove all transients which are in the group, that causes circlular pointer hell of doom */ for (it = self->group->members; it; it = g_slist_next(it)) { @@ -1622,6 +1619,8 @@ void client_update_wmhints(ObClient *self) self->can_focus = TRUE; if ((hints = XGetWMHints(ob_display, self->window)) != NULL) { + gboolean ur; + if (hints->flags & InputHint) self->can_focus = hints->input; @@ -1631,6 +1630,13 @@ void client_update_wmhints(ObClient *self) if (hints->flags & StateHint) self->iconic = hints->initial_state == IconicState; + ur = self->urgent; + self->urgent = (hints->flags & XUrgencyHint); + if (self->urgent && !ur) + client_hilite(self, TRUE); + else if (!self->urgent && ur && self->demands_attention) + client_hilite(self, FALSE); + if (!(hints->flags & WindowGroupHint)) hints->window_group = None; @@ -2189,6 +2195,12 @@ gboolean client_normal(ObClient *self) { self->type == OB_CLIENT_TYPE_SPLASH); } +gboolean client_application(ObClient *self) +{ + return (self->type == OB_CLIENT_TYPE_NORMAL || + self->type == OB_CLIENT_TYPE_DIALOG); +} + static void client_apply_startup_state(ObClient *self, gint x, gint y) { gboolean pos = FALSE; /* has the window's position been configured? */ @@ -2624,10 +2636,11 @@ static void client_iconify_recursive(ObClient *self, screen_update_areas(); } - /* iconify all direct transients */ + /* iconify all direct transients, and deiconify all transients + (non-direct too) */ for (it = self->transients; it; it = g_slist_next(it)) if (it->data != self) - if (client_is_direct_child(self, it->data)) + if (client_is_direct_child(self, it->data) || !iconic) client_iconify_recursive(it->data, iconic, curdesk); } @@ -2775,11 +2788,13 @@ void client_hilite(ObClient *self, gboolean hilite) /* don't allow focused windows to hilite */ self->demands_attention = hilite && !client_focused(self); - if (self->demands_attention) - frame_flash_start(self->frame); - else - frame_flash_stop(self->frame); - client_change_state(self); + if (self->frame != NULL) { /* if we're mapping, just set the state */ + if (self->demands_attention) + frame_flash_start(self->frame); + else + frame_flash_stop(self->frame); + client_change_state(self); + } } void client_set_desktop_recursive(ObClient *self, @@ -3621,3 +3636,17 @@ gboolean client_has_group_siblings(ObClient *self) { return self->group && self->group->members->next; } + +gboolean client_has_application_group_siblings(ObClient *self) +{ + GSList *it; + + if (!self->group) return FALSE; + + for (it = self->group->members; it; it = g_slist_next(it)) { + ObClient *c = it->data; + if (c != self && client_application(c)) + return TRUE; + } + return FALSE; +}