screen_install_colormap(client, TRUE);
/* in the middle of cycling..? kill it. */
- focus_cycle_stop();
+ focus_cycle_stop(focus_client);
+ focus_cycle_stop(client);
focus_client = client;
}
}
-static ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old,
- gboolean send_focus)
+static ObClient* focus_fallback_target(gboolean allow_refocus,
+ gboolean allow_pointer,
+ gboolean allow_omnipresent,
+ ObClient *old)
{
GList *it;
ObClient *c;
ob_debug_type(OB_DEBUG_FOCUS, "trying pointer stuff\n");
- if (config_focus_follow && !config_focus_last)
+ if (allow_pointer && config_focus_follow)
if ((c = client_under_pointer()) &&
- (allow_refocus || c != old) &&
- client_normal(c) &&
- /* if we're sending focus then try to */
- ((send_focus && client_focus(c)) ||
- /* if not just see if we could try, or it's already focused */
- (!send_focus && (c == old || client_can_focus(c)))))
+ (allow_refocus || client_focus_target(c) != old) &&
+ (client_normal(c) &&
+ client_focus(c)))
{
- ob_debug_type(OB_DEBUG_FOCUS, "found in pointer stuff (%d)\n",
- send_focus);
+ ob_debug_type(OB_DEBUG_FOCUS, "found in pointer stuff\n");
return c;
}
- ob_debug_type(OB_DEBUG_FOCUS, "trying omnipresentness\n");
- if (allow_refocus && old &&
- old->desktop == DESKTOP_ALL &&
- client_normal(old) &&
- /* this one is only for when not sending focus, to keep it there */
- !send_focus)
- {
- ob_debug_type(OB_DEBUG_FOCUS, "found in omnipresentness (%d)\n",
- send_focus);
- return old;
- }
-
-
ob_debug_type(OB_DEBUG_FOCUS, "trying the focus order\n");
for (it = focus_order; it; it = g_list_next(it)) {
c = it->data;
/* fallback focus to a window if:
1. it is on the current desktop. this ignores omnipresent
- windows, which are problematic in their own rite.
+ windows, which are problematic in their own rite, unless they are
+ specifically allowed
2. it is a normal type window, don't fall back onto a dock or
a splashscreen or a desktop window (save the desktop as a
backup fallback though)
*/
- if (c->desktop == screen_desktop &&
+ if ((allow_omnipresent || c->desktop == screen_desktop) &&
client_normal(c) &&
- (allow_refocus || c != old) &&
- /* if we're sending focus then try to */
- ((send_focus && client_focus(c)) ||
- /* if not just see if we could try, or it's already focused */
- (!send_focus && (c == old || client_can_focus(c)))))
+ (allow_refocus || client_focus_target(c) != old) &&
+ client_focus(c))
{
- ob_debug_type(OB_DEBUG_FOCUS, "found in focus order (%d) 0x%x "
- "from 0x%x\n",
- send_focus, c, old);
+ ob_debug_type(OB_DEBUG_FOCUS, "found in focus order\n");
return c;
}
}
backup fallback though)
*/
if (c->type == OB_CLIENT_TYPE_DESKTOP &&
- (allow_refocus || c != old) &&
- /* if we're sending focus then try to */
- ((send_focus && client_focus(c)) ||
- /* if not just see if we could try, or it's already focused */
- (!send_focus && (c == old || client_can_focus(c)))))
+ (allow_refocus || client_focus_target(c) != old) &&
+ client_focus(c))
{
- ob_debug_type(OB_DEBUG_FOCUS, "found a desktop window (%d)\n",
- send_focus);
+ ob_debug_type(OB_DEBUG_FOCUS, "found a desktop window\n");
return c;
}
}
return NULL;
}
-ObClient* focus_fallback(gboolean allow_refocus)
+ObClient* focus_fallback(gboolean allow_refocus, gboolean allow_pointer,
+ gboolean allow_omnipresent)
{
ObClient *new;
ObClient *old = focus_client;
- new = focus_fallback_target(allow_refocus, old, FALSE);
- if (new == old) return;
-
/* unfocus any focused clients.. they can be focused by Pointer events
and such, and then when we try focus them, we won't get a FocusIn
event at all for them. */
focus_nothing();
- new = focus_fallback_target(allow_refocus, old, TRUE);
+ new = focus_fallback_target(allow_refocus, allow_pointer,
+ allow_omnipresent, old);
+ /* get what was really focused */
+ if (new) new = client_focus_target(new);
return new;
}
actions should not rely on being able to move focus during an
interactive grab.
*/
- if (keyboard_interactively_grabbed())
- keyboard_interactive_cancel();
+ event_cancel_all_key_grabs();
/* when nothing will be focused, send focus to the backup target */
XSetInputFocus(ob_display, screen_support_win, RevertToPointerRoot,
event_curtime);
}
+void focus_order_add_new(ObClient *c)
+{
+ if (c->iconic)
+ focus_order_to_top(c);
+ else {
+ g_assert(!g_list_find(focus_order, c));
+ /* if there are any iconic windows, put this above them in the order,
+ but if there are not, then put it under the currently focused one */
+ if (focus_order && ((ObClient*)focus_order->data)->iconic)
+ focus_order = g_list_insert(focus_order, c, 0);
+ else
+ focus_order = g_list_insert(focus_order, c, 1);
+ }
+
+ /* in the middle of cycling..? kill it. */
+ focus_cycle_stop(c);
+}
+
void focus_order_remove(ObClient *c)
{
focus_order = g_list_remove(focus_order, c);
+
+ /* in the middle of cycling..? kill it. */
+ focus_cycle_stop(c);
}
void focus_order_to_top(ObClient *c)