press +$mod+f+.
There is also a global fullscreen mode in i3 in which the client will span all
-available outputs (the command is +fullscreen global+).
+available outputs (the command is +fullscreen toggle global+).
=== Opening other applications
*Examples*:
--------------------------------
# Fullscreen
-bindsym $mod+f fullscreen
+bindsym $mod+f fullscreen toggle
# Restart
bindsym $mod+Shift+r restart
or +layout splith+ to change the current container layout to splith/splitv,
stacking, tabbed layout, splitv or splith, respectively.
-To make the current window (!) fullscreen, use +fullscreen+, to make
-it floating (or tiling again) use +floating enable+ respectively +floating disable+
-(or +floating toggle+):
+To make the current window (!) fullscreen, use +fullscreen enable+ (or
++fullscreen enable global+ for the global mode), to leave either fullscreen
+mode use +fullscreen disable+, and to toggle between these two states use
++fullscreen toggle+ (or +fullscreen toggle global+).
+
+Likewise, to make the current window floating (or tiling again) use +floating
+enable+ respectively +floating disable+ (or +floating toggle+):
*Syntax*:
--------------
bindsym $mod+x layout toggle all
# Toggle fullscreen
-bindsym $mod+f fullscreen
+bindsym $mod+f fullscreen toggle
# Toggle floating/tiling
bindsym $mod+t floating toggle
bindsym Mod1+v split v
# enter fullscreen mode for the focused container
-bindsym Mod1+f fullscreen
+bindsym Mod1+f fullscreen toggle
# change container layout (stacked, tabbed, toggle split)
bindsym Mod1+s layout stacking
bindcode $mod+55 split v
# enter fullscreen mode for the focused container
-bindcode $mod+41 fullscreen
+bindcode $mod+41 fullscreen toggle
# change container layout (stacked, tabbed, toggle split)
bindcode $mod+39 layout stacking
void cmd_focus(I3_CMD);
/**
- * Implementation of 'fullscreen [global]'.
+ * Implementation of 'fullscreen [enable|disable|toggle] [global]'.
*
*/
-void cmd_fullscreen(I3_CMD, char *fullscreen_mode);
+void cmd_fullscreen(I3_CMD, char *action, char *fullscreen_mode);
/**
* Implementation of 'move <direction> [<pixels> [px]]'.
*/
void con_toggle_fullscreen(Con *con, int fullscreen_mode);
+/**
+ * Enables fullscreen mode for the given container, if necessary.
+ *
+ */
+void con_enable_fullscreen(Con *con, fullscreen_mode_t fullscreen_mode);
+
+/**
+ * Disables fullscreen mode for the given container, if necessary.
+ *
+ */
+void con_disable_fullscreen(Con *con);
+
/**
* Moves the given container to the currently focused container on the given
* workspace.
bindsym Mod1+v split v
# enter fullscreen mode for the focused container
-bindsym Mod1+f fullscreen
+bindsym Mod1+f fullscreen toggle
# change container layout (stacked, tabbed, default)
bindsym Mod1+s layout stacking
end
-> call cmd_kill($kill_mode)
+# fullscreen enable|toggle [global]
+# fullscreen disable
# fullscreen [global]
state FULLSCREEN:
- fullscreen_mode = 'global'
- -> call cmd_fullscreen($fullscreen_mode)
+ action = 'disable'
+ -> call cmd_fullscreen($action, "output")
+ action = 'enable', 'toggle'
+ -> FULLSCREEN_MODE
+ action = ''
+ -> FULLSCREEN_COMPAT
+
+state FULLSCREEN_MODE:
+ mode = 'global'
+ -> call cmd_fullscreen($action, $mode)
end
- -> call cmd_fullscreen($fullscreen_mode)
+ -> call cmd_fullscreen($action, "output")
+
+state FULLSCREEN_COMPAT:
+ mode = 'global'
+ -> call cmd_fullscreen("toggle", $mode)
+ end
+ -> call cmd_fullscreen("toggle", "output")
# split v|h|vertical|horizontal
state SPLIT:
}
/*
- * Implementation of 'fullscreen [global]'.
+ * Implementation of 'fullscreen enable|toggle [global]' and
+ * 'fullscreen disable'
*
*/
-void cmd_fullscreen(I3_CMD, char *fullscreen_mode) {
- if (fullscreen_mode == NULL)
- fullscreen_mode = "output";
- DLOG("toggling fullscreen, mode = %s\n", fullscreen_mode);
+void cmd_fullscreen(I3_CMD, char *action, char *fullscreen_mode) {
+ fullscreen_mode_t mode = strcmp(fullscreen_mode, "global") == 0 ? CF_GLOBAL : CF_OUTPUT;
+ DLOG("%s fullscreen, mode = %s\n", action, fullscreen_mode);
owindow *current;
HANDLE_EMPTY_MATCH;
TAILQ_FOREACH(current, &owindows, owindows) {
DLOG("matching: %p / %s\n", current->con, current->con->name);
- con_toggle_fullscreen(current->con, (strcmp(fullscreen_mode, "global") == 0 ? CF_GLOBAL : CF_OUTPUT));
+ if (strcmp(action, "toggle") == 0) {
+ con_toggle_fullscreen(current->con, mode);
+ } else if (strcmp(action, "enable") == 0) {
+ con_enable_fullscreen(current->con, mode);
+ } else if (strcmp(action, "disable") == 0) {
+ con_disable_fullscreen(current->con);
+ }
}
cmd_output->needs_tree_render = true;
*
*/
void con_toggle_fullscreen(Con *con, int fullscreen_mode) {
- Con *workspace, *fullscreen;
-
if (con->type == CT_WORKSPACE) {
DLOG("You cannot make a workspace fullscreen.\n");
return;
}
DLOG("toggling fullscreen for %p / %s\n", con, con->name);
- if (con->fullscreen_mode == CF_NONE) {
- /* 1: check if there already is a fullscreen con */
- if (fullscreen_mode == CF_GLOBAL)
- fullscreen = con_get_fullscreen_con(croot, CF_GLOBAL);
- else {
- workspace = con_get_workspace(con);
- fullscreen = con_get_fullscreen_con(workspace, CF_OUTPUT);
- }
- if (fullscreen != NULL) {
- /* Disable fullscreen for the currently fullscreened
- * container and enable it for the one the user wants
- * to have in fullscreen mode. */
- LOG("Disabling fullscreen for (%p/%s) upon user request\n",
- fullscreen, fullscreen->name);
- fullscreen->fullscreen_mode = CF_NONE;
- }
- /* 2: enable fullscreen */
- con->fullscreen_mode = fullscreen_mode;
- } else {
- /* 1: disable fullscreen */
- con->fullscreen_mode = CF_NONE;
- }
+ if (con->fullscreen_mode == CF_NONE)
+ con_enable_fullscreen(con, fullscreen_mode);
+ else
+ con_disable_fullscreen(con);
+}
+
+/*
+ * Sets the specified fullscreen mode for the given container, sends the
+ * “fullscreen_mode” event and changes the XCB fullscreen property of the
+ * container’s window, if any.
+ *
+ */
+static void con_set_fullscreen_mode(Con *con, fullscreen_mode_t fullscreen_mode) {
+ con->fullscreen_mode = fullscreen_mode;
DLOG("mode now: %d\n", con->fullscreen_mode);
A__NET_WM_STATE, XCB_ATOM_ATOM, 32, num, values);
}
+/*
+ * Enables fullscreen mode for the given container, if necessary.
+ *
+ * If the container’s mode is already CF_OUTPUT or CF_GLOBAL, the container is
+ * kept fullscreen but its mode is set to CF_GLOBAL and CF_OUTPUT,
+ * respectively.
+ *
+ * Other fullscreen containers will be disabled first, if they hide the new
+ * one.
+ *
+ */
+void con_enable_fullscreen(Con *con, fullscreen_mode_t fullscreen_mode) {
+ if (con->type == CT_WORKSPACE) {
+ DLOG("You cannot make a workspace fullscreen.\n");
+ return;
+ }
+
+ assert(fullscreen_mode == CF_GLOBAL || fullscreen_mode == CF_OUTPUT);
+
+ if (fullscreen_mode == CF_GLOBAL)
+ DLOG("enabling global fullscreen for %p / %s\n", con, con->name);
+ else
+ DLOG("enabling fullscreen for %p / %s\n", con, con->name);
+
+ if (con->fullscreen_mode == fullscreen_mode) {
+ DLOG("fullscreen already enabled for %p / %s\n", con, con->name);
+ return;
+ }
+
+ Con *con_ws = con_get_workspace(con);
+
+ /* Disable any fullscreen container that would conflict the new one. */
+ Con *fullscreen = con_get_fullscreen_con(croot, CF_GLOBAL);
+ if (fullscreen == NULL)
+ fullscreen = con_get_fullscreen_con(con_ws, CF_OUTPUT);
+ if (fullscreen != NULL)
+ con_disable_fullscreen(fullscreen);
+
+ /* Set focus to new fullscreen container. Unless in global fullscreen mode
+ * and on another workspace restore focus afterwards.
+ * Switch to the container’s workspace if mode is global. */
+ Con *cur_ws = con_get_workspace(focused);
+ Con *old_focused = focused;
+ if (fullscreen_mode == CF_GLOBAL && cur_ws != con_ws)
+ workspace_show(con_ws);
+ con_focus(con);
+ if (fullscreen_mode != CF_GLOBAL && cur_ws != con_ws)
+ con_focus(old_focused);
+
+ con_set_fullscreen_mode(con, fullscreen_mode);
+}
+
+/*
+ * Disables fullscreen mode for the given container regardless of the mode, if
+ * necessary.
+ *
+ */
+void con_disable_fullscreen(Con *con) {
+ if (con->type == CT_WORKSPACE) {
+ DLOG("You cannot make a workspace fullscreen.\n");
+ return;
+ }
+
+ DLOG("disabling fullscreen for %p / %s\n", con, con->name);
+
+ if (con->fullscreen_mode == CF_NONE) {
+ DLOG("fullscreen already disabled for %p / %s\n", con, con->name);
+ return;
+ }
+
+ con_set_fullscreen_mode(con, CF_NONE);
+}
+
/*
* Moves the given container to the currently focused container on the given
* workspace.
bindsym Mod1+v split v
# Fullscreen (Mod1+f)
-bindsym Mod1+f fullscreen
+bindsym Mod1+f fullscreen toggle
# Stacking (Mod1+s)
bindsym Mod1+s layout stacking
is(fullscreen_windows($tmp), 1, 'one fullscreen window on ws');
is($x->input_focus, $swindow->id, 'fullscreen window focused');
+################################################################################
+# Verify that command ‘fullscreen enable’ works and is idempotent.
+################################################################################
+
+$tmp = fresh_workspace;
+
+$window = open_window;
+is($x->input_focus, $window->id, 'window focused');
+is(fullscreen_windows($tmp), 0, 'no fullscreen window on workspace');
+
+cmd 'fullscreen enable';
+is($x->input_focus, $window->id, 'window still focused');
+is(fullscreen_windows($tmp), 1, 'one fullscreen window on workspace');
+
+cmd 'fullscreen enable';
+is($x->input_focus, $window->id, 'window still focused');
+is(fullscreen_windows($tmp), 1, 'still one fullscreen window on workspace');
+
+$window->fullscreen(0);
+sync_with_i3;
+is(fullscreen_windows($tmp), 0, 'no fullscreen window on workspace');
+
+################################################################################
+# Verify that command ‘fullscreen enable global’ works and is idempotent.
+################################################################################
+
+$tmp = fresh_workspace;
+
+$window = open_window;
+is($x->input_focus, $window->id, 'window focused');
+is(fullscreen_windows($tmp), 0, 'no fullscreen window on workspace');
+
+cmd 'fullscreen enable global';
+is($x->input_focus, $window->id, 'window still focused');
+is(fullscreen_windows($tmp), 1, 'one fullscreen window on workspace');
+
+cmd 'fullscreen enable global';
+is($x->input_focus, $window->id, 'window still focused');
+is(fullscreen_windows($tmp), 1, 'still one fullscreen window on workspace');
+
+$window->fullscreen(0);
+sync_with_i3;
+is(fullscreen_windows($tmp), 0, 'no fullscreen window on workspace');
+
+################################################################################
+# Verify that command ‘fullscreen disable’ works and is idempotent.
+################################################################################
+
+$tmp = fresh_workspace;
+
+$window = open_window;
+is($x->input_focus, $window->id, 'window focused');
+is(fullscreen_windows($tmp), 0, 'no fullscreen window on workspace');
+
+$window->fullscreen(1);
+sync_with_i3;
+is(fullscreen_windows($tmp), 1, 'one fullscreen window on workspace');
+
+cmd 'fullscreen disable';
+is($x->input_focus, $window->id, 'window still focused');
+is(fullscreen_windows($tmp), 0, 'no fullscreen window on workspace');
+
+cmd 'fullscreen disable';
+is($x->input_focus, $window->id, 'window still focused');
+is(fullscreen_windows($tmp), 0, 'still no fullscreen window on workspace');
+
+################################################################################
+# Verify that command ‘fullscreen toggle’ works.
+################################################################################
+
+$tmp = fresh_workspace;
+
+$window = open_window;
+is(fullscreen_windows($tmp), 0, 'no fullscreen window on workspace');
+
+cmd 'fullscreen toggle';
+is($x->input_focus, $window->id, 'window still focused');
+is(fullscreen_windows($tmp), 1, 'one fullscreen window on workspace');
+
+cmd 'fullscreen toggle';
+is($x->input_focus, $window->id, 'window still focused');
+is(fullscreen_windows($tmp), 0, 'no fullscreen window on workspace');
+
+################################################################################
+# Verify that a window’s fullscreen is disabled when another one is enabled
+# on the same workspace. The new fullscreen window should be focused.
+################################################################################
+
+$tmp = fresh_workspace;
+
+$window = open_window;
+$other = open_window;
+
+is($x->input_focus, $other->id, 'other window focused');
+is(fullscreen_windows($tmp), 0, 'no fullscreen window on workspace');
+
+cmd 'fullscreen enable';
+is($x->input_focus, $other->id, 'other window focused');
+is(fullscreen_windows($tmp), 1, 'one fullscreen window on workspace');
+
+cmd '[id="' . $window->id . '"] fullscreen enable';
+is($x->input_focus, $window->id, 'window focused');
+is(fullscreen_windows($tmp), 1, 'one fullscreen window on workspace');
+
+################################################################################
+# Verify that when a global fullscreen is enabled the window is focused and
+# its workspace is selected, so that disabling the fullscreen keeps the window
+# focused and visible.
+################################################################################
+
+$tmp = fresh_workspace;
+
+$window = open_window;
+
+is($x->input_focus, $window->id, 'window focused');
+
+cmd 'workspace ' . get_unused_workspace;
+isnt($x->input_focus, $window->id, 'window not focused');
+isnt(focused_ws(), $tmp, 'workspace not selected');
+
+cmd '[id="' . $window->id . '"] fullscreen enable global';
+is($x->input_focus, $window->id, 'window focused');
+
+cmd 'fullscreen disable';
+is($x->input_focus, $window->id, 'window still focused');
+is(focused_ws(), $tmp, 'workspace selected');
+
done_testing;