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)
{
g_assert(self != NULL);
- /* update the focus lists */
- focus_order_remove(self);
+ frame_hide(self->frame);
+ XSync(ob_display, FALSE);
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);
/* we dont want events no more */
XSelectInput(ob_display, self->window, NoEventMask);
+ /* update the focus lists */
+ focus_order_remove(self);
+
client_list = g_list_remove(client_list, self);
stacking_remove(self);
g_hash_table_remove(window_map, &self->window);
/* update the list hints */
client_set_list();
-
- if (config_focus_last)
- grab_pointer(FALSE, OB_CURSOR_NONE);
}
static ObAppSettings *client_get_settings_state(ObClient *self)
return TRUE;
}
-/* Used when the current client is closed or otherwise hidden, focus_last will
- then prevent focus from going to the mouse pointer
-*/
-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(FALSE);
- }
-}
-
void client_activate(ObClient *self, gboolean here, gboolean user)
{
guint32 last_time = focus_client ? focus_client->user_time : CurrentTime;
return keyboard_interactively_grabbed();
case FocusIn:
case FocusOut:
- /* I don't think this should ever happen with our event masks, but
- if it does, we don't want it. */
- if (client == NULL)
- return TRUE;
- if (!wanted_focusevent(e))
+ if (!wanted_focusevent(e)) {
+ ob_debug_type(OB_DEBUG_FOCUS, "focus event ignored\n");
return TRUE;
+ }
+ ob_debug_type(OB_DEBUG_FOCUS, "focus event used;\n");
break;
}
return FALSE;
{
/* crossing events for menu */
event_handle_menu(e);
+ } else if (e->type == FocusIn) {
+ if (e->xfocus.detail == NotifyPointerRoot ||
+ e->xfocus.detail == NotifyDetailNone) {
+ ob_debug_type(OB_DEBUG_FOCUS, "Focus went to root\n");
+ /* Focus has been reverted to the root window or nothing, so fall
+ back to something other than the window which just had it. */
+ focus_fallback(FALSE);
+ } else if (e->xfocus.detail == NotifyInferior) {
+ ob_debug_type(OB_DEBUG_FOCUS, "Focus went to parent\n");
+ /* Focus has been reverted to parent, which is our frame window,
+ or the root window, so fall back to something other than the
+ window which had it. */
+ focus_fallback(FALSE);
+ } else if (client && client != focus_client) {
+ focus_set_client(client);
+ frame_adjust_focus(client->frame, TRUE);
+ client_calc_layer(client);
+ }
+ } else if (e->type == FocusOut) {
+ gboolean nomove = FALSE;
+ XEvent ce;
+
+ ob_debug_type(OB_DEBUG_FOCUS, "FocusOut Event\n");
+
+ /* Look for the followup FocusIn */
+ if (!XCheckIfEvent(ob_display, &ce, look_for_focusin, NULL)) {
+ /* There is no FocusIn, this means focus went to a window that
+ is not being managed, or a window on another screen. */
+ ob_debug_type(OB_DEBUG_FOCUS, "Focus went to a black hole !\n");
+ } else if (ce.xany.window == e->xany.window) {
+ /* If focus didn't actually move anywhere, there is nothing to do*/
+ nomove = TRUE;
+ } else {
+ /* Focus did move, so process the FocusIn event */
+ ObEventData ed = { .ignored = FALSE };
+ event_process(&ce, &ed);
+ if (ed.ignored) {
+ /* The FocusIn was ignored, this means it was on a window
+ that isn't a client. */
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "Focus went to an unmanaged window 0x%x !\n",
+ ce.xfocus.window);
+ focus_fallback(TRUE);
+ }
+ }
+
+ if (client && !nomove) {
+ /* This client is no longer focused, so show that */
+ focus_hilite = NULL;
+ frame_adjust_focus(client->frame, FALSE);
+ client_calc_layer(client);
+ }
} else if (group)
event_handle_group(group, e);
else if (client)
}
}
break;
- case FocusIn:
- if (client != focus_client) {
- focus_set_client(client);
- frame_adjust_focus(client->frame, TRUE);
- client_calc_layer(client);
- }
- break;
- case FocusOut:
- /* Look for the followup FocusIn */
- if (!XCheckIfEvent(ob_display, &ce, look_for_focusin, NULL)) {
- /* There is no FocusIn, this means focus went to a window that
- is not being managed, or a window on another screen. */
- ob_debug_type(OB_DEBUG_FOCUS, "Focus went to a black hole !\n");
- } else if (ce.xany.window == e->xany.window) {
- /* If focus didn't actually move anywhere, there is nothing to do*/
- break;
- } else if (ce.xfocus.detail == NotifyPointerRoot ||
- ce.xfocus.detail == NotifyDetailNone) {
- ob_debug_type(OB_DEBUG_FOCUS, "Focus went to root\n");
- /* Focus has been reverted to the root window or nothing, so fall
- back to something other than the window which just had it. */
- focus_fallback(FALSE);
- } else if (ce.xfocus.detail == NotifyInferior) {
- ob_debug_type(OB_DEBUG_FOCUS, "Focus went to parent\n");
- /* Focus has been reverted to parent, which is our frame window,
- or the root window, so fall back to something other than the
- window which had it. */
- focus_fallback(FALSE);
- } else {
- /* Focus did move, so process the FocusIn event */
- ObEventData ed = { .ignored = FALSE };
- event_process(&ce, &ed);
- if (ed.ignored) {
- /* The FocusIn was ignored, this means it was on a window
- that isn't a client. */
- ob_debug_type(OB_DEBUG_FOCUS,
- "Focus went to an unmanaged window 0x%x !\n",
- ce.xfocus.window);
- focus_fallback(TRUE);
- }
- }
-
- /* This client is no longer focused, so show that */
- focus_hilite = NULL;
- frame_adjust_focus(client->frame, FALSE);
- client_calc_layer(client);
- break;
case LeaveNotify:
con = frame_context(client, e->xcrossing.window);
switch (con) {