*
*/
static bool _tree_next(Con *con, char way, orientation_t orientation, bool wrap) {
+ /* When dealing with fullscreen containers, it's necessary to go up to the
+ * workspace level, because 'focus $dir' will start at the con's real
+ * position in the tree, and it may not be possible to get to the edge
+ * normally due to fullscreen focusing restrictions. */
+ if (con->fullscreen_mode == CF_OUTPUT && con->type != CT_WORKSPACE)
+ con = con_get_workspace(con);
+
/* Stop recursing at workspaces after attempting to switch to next
* workspace if possible. */
if (con->type == CT_WORKSPACE) {
- if (con_get_fullscreen_con(con, CF_GLOBAL) ||
- con_get_fullscreen_con(con, CF_OUTPUT)) {
- DLOG("Cannot change workspace while in fullscreen mode.\n");
+ if (con_get_fullscreen_con(con, CF_GLOBAL)) {
+ DLOG("Cannot change workspace while in global fullscreen mode.\n");
return false;
}
Output *current_output = get_output_containing(con->rect.x, con->rect.y);
return false;
workspace_show(workspace);
+
+ /* If a workspace has an active fullscreen container, one of its
+ * children should always be focused. The above workspace_show()
+ * should be adequate for that, so return. */
+ if (con_get_fullscreen_con(workspace, CF_OUTPUT))
+ return true;
+
Con *focus = con_descend_direction(workspace, direction);
if (focus) {
con_focus(focus);
cmd 'fullscreen';
+# Focus screen 1
+$x->root->warp_pointer(1025, 0);
+sync_with_i3;
+
$tmp = fresh_workspace;
cmd "workspace $tmp";
my $diff_ws = open_window;
+# Focus screen 0
+$x->root->warp_pointer(0, 0);
+sync_with_i3;
+
$tmp2 = fresh_workspace;
cmd "workspace $tmp2";
cmd 'split h';
cmd 'focus down';
is($x->input_focus, $right2->id, 'allowed focus down');
-cmd 'focus left';
-is($x->input_focus, $right2->id, 'prevented focus left');
-
-cmd 'focus right';
-is($x->input_focus, $right2->id, 'prevented focus right');
-
cmd 'focus down';
is($x->input_focus, $right1->id, 'allowed focus wrap (down)');
cmd 'focus up';
is($x->input_focus, $right2->id, 'allowed focus wrap (up)');
-cmd '[id="' . $diff_ws->id . '"] focus';
+cmd 'focus left';
+is($x->input_focus, $right2->id, 'focus left wrapped (no-op)');
+
+cmd 'focus right';
is($x->input_focus, $diff_ws->id, 'allowed focus change to different ws');
+cmd 'focus left';
+is($x->input_focus, $right2->id, 'focused back into fullscreen container');
+
+cmd '[id="' . $diff_ws->id . '"] focus';
+is($x->input_focus, $diff_ws->id, 'allowed focus change to different ws by id');
+
################################################################################
# More testing of the interaction between wrapping and the fullscreen focus
# restrictions.