} while (0)
/** When the command did not include match criteria (!), we use the currently
- * focused command. Do not confuse this case with a command which included
+ * focused container. Do not confuse this case with a command which included
* criteria but which did not match any windows. This macro has to be called in
* every command.
*/
/*
* Implementation of 'move [window|container] [to] workspace
- * next|prev|next_on_output|prev_on_output'.
+ * next|prev|next_on_output|prev_on_output|current'.
*
*/
void cmd_move_con_to_workspace(I3_CMD, char *which) {
DLOG("which=%s\n", which);
+ /* We have nothing to move:
+ * when criteria was specified but didn't match any window or
+ * when criteria wasn't specified and we don't have any window focused. */
+ if ((!match_is_empty(current_match) && TAILQ_EMPTY(&owindows)) ||
+ (match_is_empty(current_match) && focused->type == CT_WORKSPACE)) {
+ ysuccess(false);
+ return;
+ }
+
HANDLE_EMPTY_MATCH;
/* get the workspace */
ws = workspace_next_on_output();
else if (strcmp(which, "prev_on_output") == 0)
ws = workspace_prev_on_output();
+ else if (strcmp(which, "current") == 0)
+ ws = con_get_workspace(focused);
else {
ELOG("BUG: called with which=%s\n", which);
ysuccess(false);
owindow *current;
- /* Error out early to not create a non-existing workspace (in
- * workspace_get()) if we are not actually able to move anything. */
- if (match_is_empty(current_match) && focused->type == CT_WORKSPACE) {
+ /* We have nothing to move:
+ * when criteria was specified but didn't match any window or
+ * when criteria wasn't specified and we don't have any window focused. */
+ if ((!match_is_empty(current_match) && TAILQ_EMPTY(&owindows)) ||
+ (match_is_empty(current_match) && focused->type == CT_WORKSPACE)) {
ysuccess(false);
return;
}
void cmd_move_con_to_workspace_number(I3_CMD, char *which) {
owindow *current;
- /* Error out early to not create a non-existing workspace (in
- * workspace_get()) if we are not actually able to move anything. */
- if (match_is_empty(current_match) && focused->type == CT_WORKSPACE) {
+ /* We have nothing to move:
+ * when criteria was specified but didn't match any window or
+ * when criteria wasn't specified and we don't have any window focused. */
+ if ((!match_is_empty(current_match) && TAILQ_EMPTY(&owindows)) ||
+ (match_is_empty(current_match) && focused->type == CT_WORKSPACE)) {
ysuccess(false);
return;
}
*
*/
void cmd_focus_level(I3_CMD, char *level) {
- if (focused &&
- focused->type != CT_WORKSPACE &&
- focused->fullscreen_mode != CF_NONE) {
- LOG("Cannot change focus while in fullscreen mode.\n");
- ysuccess(false);
- return;
- }
-
DLOG("level = %s\n", level);
+ bool success = false;
+
+ /* Focusing the parent can only be allowed if the newly
+ * focused container won't escape the fullscreen container. */
+ if (strcmp(level, "parent") == 0) {
+ if (focused && focused->parent) {
+ if (con_fullscreen_permits_focusing(focused->parent))
+ success = level_up();
+ else
+ LOG("Currently in fullscreen, not going up\n");
+ }
+ }
- if (strcmp(level, "parent") == 0)
- level_up();
- else level_down();
+ /* Focusing a child should always be allowed. */
+ else success = level_down();
- cmd_output->needs_tree_render = true;
+ cmd_output->needs_tree_render = success;
// XXX: default reply for now, make this a better reply
- ysuccess(true);
+ ysuccess(success);
}
/*
if (!ws)
continue;
- /* Don't allow the focus switch if the focused and current
- * containers are in the same workspace. */
- if (focused &&
- focused->type != CT_WORKSPACE &&
- focused->fullscreen_mode != CF_NONE &&
- con_get_workspace(focused) == ws) {
- LOG("Cannot change focus while in fullscreen mode (same workspace).\n");
+ /* Check the fullscreen focus constraints. */
+ if (!con_fullscreen_permits_focusing(current->con)) {
+ LOG("Cannot change focus while in fullscreen mode (fullscreen rules).\n");
ysuccess(false);
return;
}
*/
void cmd_exit(I3_CMD) {
LOG("Exiting due to user command.\n");
+ xcb_disconnect(conn);
exit(0);
/* unreached */