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
/* 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
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)
!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);
/* 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);
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);
}
}
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)) {
self->can_focus = TRUE;
if ((hints = XGetWMHints(ob_display, self->window)) != NULL) {
+ gboolean ur;
+
if (hints->flags & InputHint)
self->can_focus = hints->input;
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;
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? */
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);
}
/* 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,
{
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;
+}