more progresses
This commit is contained in:
parent
c8f383329d
commit
03cbf0a766
|
@ -2,35 +2,19 @@ static void GENERATED_call(const int call_identifier, struct CommandResultIR *re
|
|||
switch (call_identifier) {
|
||||
case 0:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_rename_workspace(¤t_match, result, "to", get_string("new_name"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_rename_workspace(%s, %s)\n", "to", get_string("new_name"));
|
||||
#endif
|
||||
break;
|
||||
case 1:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_rename_workspace(¤t_match, result, NULL, "to");
|
||||
#else
|
||||
fprintf(stderr, "cmd_rename_workspace(NULL, %s)\n", "to");
|
||||
#endif
|
||||
break;
|
||||
case 2:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_rename_workspace(¤t_match, result, get_string("old_name"), get_string("new_name"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_rename_workspace(%s, %s)\n", get_string("old_name"), get_string("new_name"));
|
||||
#endif
|
||||
break;
|
||||
case 3:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_rename_workspace(¤t_match, result, NULL, get_string("new_name"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_rename_workspace(NULL, %s)\n", get_string("new_name"));
|
||||
#endif
|
||||
break;
|
||||
case 4:
|
||||
result->next_state = INITIAL;
|
||||
|
@ -186,43 +170,23 @@ static void GENERATED_call(const int call_identifier, struct CommandResultIR *re
|
|||
break;
|
||||
case 23:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_move_con_to_workspace(¤t_match, result, get_string("workspace"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_move_con_to_workspace(%s)\n", get_string("workspace"));
|
||||
#endif
|
||||
break;
|
||||
case 24:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_move_con_to_workspace(¤t_match, result, get_string("workspace"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_move_con_to_workspace(%s)\n", get_string("workspace"));
|
||||
#endif
|
||||
break;
|
||||
case 25:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_move_con_to_workspace(¤t_match, result, get_string("workspace"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_move_con_to_workspace(%s)\n", get_string("workspace"));
|
||||
#endif
|
||||
break;
|
||||
case 26:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_move_con_to_workspace(¤t_match, result, get_string("workspace"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_move_con_to_workspace(%s)\n", get_string("workspace"));
|
||||
#endif
|
||||
break;
|
||||
case 27:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_move_con_to_workspace(¤t_match, result, get_string("workspace"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_move_con_to_workspace(%s)\n", get_string("workspace"));
|
||||
#endif
|
||||
break;
|
||||
case 28:
|
||||
result->next_state = INITIAL;
|
||||
|
@ -250,19 +214,11 @@ static void GENERATED_call(const int call_identifier, struct CommandResultIR *re
|
|||
break;
|
||||
case 31:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_layout_toggle(¤t_match, result, get_string("toggle_mode"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_layout_toggle(%s)\n", get_string("toggle_mode"));
|
||||
#endif
|
||||
break;
|
||||
case 32:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_layout_toggle(¤t_match, result, get_string("toggle_mode"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_layout_toggle(%s)\n", get_string("toggle_mode"));
|
||||
#endif
|
||||
break;
|
||||
case 33:
|
||||
result->next_state = INITIAL;
|
||||
|
@ -514,51 +470,27 @@ static void GENERATED_call(const int call_identifier, struct CommandResultIR *re
|
|||
break;
|
||||
case 64:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_layout(¤t_match, result, get_string("layout_mode"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_layout(%s)\n", get_string("layout_mode"));
|
||||
#endif
|
||||
break;
|
||||
case 65:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_layout(¤t_match, result, get_string("layout_mode"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_layout(%s)\n", get_string("layout_mode"));
|
||||
#endif
|
||||
break;
|
||||
case 66:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_layout(¤t_match, result, get_string("layout_mode"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_layout(%s)\n", get_string("layout_mode"));
|
||||
#endif
|
||||
break;
|
||||
case 67:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_layout(¤t_match, result, get_string("layout_mode"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_layout(%s)\n", get_string("layout_mode"));
|
||||
#endif
|
||||
break;
|
||||
case 68:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_layout(¤t_match, result, get_string("layout_mode"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_layout(%s)\n", get_string("layout_mode"));
|
||||
#endif
|
||||
break;
|
||||
case 69:
|
||||
result->next_state = INITIAL;
|
||||
#ifndef TEST_PARSER
|
||||
cmd_layout(¤t_match, result, get_string("layout_mode"));
|
||||
#else
|
||||
fprintf(stderr, "cmd_layout(%s)\n", get_string("layout_mode"));
|
||||
#endif
|
||||
break;
|
||||
case 70:
|
||||
result->next_state = INITIAL;
|
||||
|
|
|
@ -44,7 +44,7 @@ void cmd_criteria_add(I3_CMD, const char *ctype, const char *cvalue);
|
|||
* next|prev|next_on_output|prev_on_output'.
|
||||
*
|
||||
*/
|
||||
void cmd_move_con_to_workspace(I3_CMD, const char *which);
|
||||
SCM guile_move_con_to_workspace(SCM which);
|
||||
|
||||
/**
|
||||
* Implementation of 'move [window|container] [to] workspace back_and_forth'.
|
||||
|
@ -218,13 +218,13 @@ void cmd_move_direction(I3_CMD, const char *direction_str, long move_px);
|
|||
* Implementation of 'layout default|stacked|stacking|tabbed|splitv|splith'.
|
||||
*
|
||||
*/
|
||||
void cmd_layout(I3_CMD, const char *layout_str);
|
||||
SCM guile_layout(SCM layout);
|
||||
|
||||
/**
|
||||
* Implementation of 'layout toggle [all|split]'.
|
||||
*
|
||||
*/
|
||||
void cmd_layout_toggle(I3_CMD, const char *toggle_mode);
|
||||
SCM guile_layout_toggle(SCM toggle_mode);
|
||||
|
||||
/**
|
||||
* Implementation of 'exit'.
|
||||
|
@ -302,7 +302,7 @@ void cmd_title_format(I3_CMD, const char *format);
|
|||
* Implementation of 'rename workspace <name> to <name>'
|
||||
*
|
||||
*/
|
||||
void cmd_rename_workspace(I3_CMD, const char *old_name, const char *new_name);
|
||||
SCM guile_rename_workspace(SCM old_name, SCM new_name);
|
||||
|
||||
/**
|
||||
* Implementation of 'bar mode dock|hide|invisible|toggle [<bar_id>]'
|
||||
|
|
508
src/commands.c
508
src/commands.c
|
@ -296,33 +296,66 @@ static void move_matches_to_workspace(Con *ws) {
|
|||
* next|prev|next_on_output|prev_on_output|current'.
|
||||
*
|
||||
*/
|
||||
void cmd_move_con_to_workspace(I3_CMD, const char *which) {
|
||||
DLOG("which=%s\n", which);
|
||||
// FIXME: NOT WORKING
|
||||
SCM guile_move_con_to_workspace(SCM g_which) {
|
||||
const char * which = scm_to_locale_string(g_which);
|
||||
|
||||
CHECK_MOVE_CON_TO_WORKSPACE;
|
||||
DLOG("which=%s\n", which);
|
||||
|
||||
/* get the workspace */
|
||||
Con *ws;
|
||||
if (strcmp(which, "next") == 0)
|
||||
ws = workspace_next();
|
||||
else if (strcmp(which, "prev") == 0)
|
||||
ws = workspace_prev();
|
||||
else if (strcmp(which, "next_on_output") == 0)
|
||||
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 {
|
||||
yerror("BUG: called with which=%s", which);
|
||||
return;
|
||||
while (!TAILQ_EMPTY(&owindows)) {
|
||||
owindow *ow = TAILQ_FIRST(&owindows);
|
||||
TAILQ_REMOVE(&owindows, ow, owindows);
|
||||
free(ow);
|
||||
}
|
||||
owindow *ow = smalloc(sizeof(owindow));
|
||||
ow->con = focused;
|
||||
TAILQ_INIT(&owindows);
|
||||
TAILQ_INSERT_TAIL(&owindows, ow, owindows);
|
||||
|
||||
|
||||
if (TAILQ_EMPTY(&owindows)) {
|
||||
/* yerror("Nothing to move: specified criteria don't match any window"); */
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
bool found = false;
|
||||
owindow *current = TAILQ_FIRST(&owindows);
|
||||
while (current) {
|
||||
owindow *next = TAILQ_NEXT(current, owindows);
|
||||
|
||||
if (current->con->type == CT_WORKSPACE && !con_has_children(current->con)) {
|
||||
TAILQ_REMOVE(&owindows, current, owindows);
|
||||
} else {
|
||||
found = true;
|
||||
}
|
||||
|
||||
move_matches_to_workspace(ws);
|
||||
current = next;
|
||||
}
|
||||
if (!found) {
|
||||
/* yerror("Nothing to move: workspace empty"); */
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
|
||||
cmd_output->needs_tree_render = true;
|
||||
// XXX: default reply for now, make this a better reply
|
||||
ysuccess(true);
|
||||
/* get the workspace */
|
||||
Con *ws;
|
||||
if (strcmp(which, "next") == 0)
|
||||
ws = workspace_next();
|
||||
else if (strcmp(which, "prev") == 0)
|
||||
ws = workspace_prev();
|
||||
else if (strcmp(which, "next_on_output") == 0)
|
||||
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 {
|
||||
/* yerror("BUG: called with which=%s", which); */
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
|
||||
move_matches_to_workspace(ws);
|
||||
|
||||
tree_render();
|
||||
return SCM_BOOL_T;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1381,113 +1414,6 @@ void cmd_sticky(I3_CMD, const char *action) {
|
|||
ysuccess(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of 'move <direction> [<pixels> [px]]'.
|
||||
*
|
||||
*/
|
||||
void cmd_move_direction(I3_CMD, const char *direction_str, long move_px) {
|
||||
owindow *current;
|
||||
HANDLE_EMPTY_MATCH;
|
||||
|
||||
Con *initially_focused = focused;
|
||||
direction_t direction = parse_direction(direction_str);
|
||||
|
||||
TAILQ_FOREACH (current, &owindows, owindows) {
|
||||
DLOG("moving in direction %s, px %ld\n", direction_str, move_px);
|
||||
if (con_is_floating(current->con)) {
|
||||
DLOG("floating move with %ld pixels\n", move_px);
|
||||
Rect newrect = current->con->parent->rect;
|
||||
|
||||
switch (direction) {
|
||||
case D_LEFT:
|
||||
newrect.x -= move_px;
|
||||
break;
|
||||
case D_RIGHT:
|
||||
newrect.x += move_px;
|
||||
break;
|
||||
case D_UP:
|
||||
newrect.y -= move_px;
|
||||
break;
|
||||
case D_DOWN:
|
||||
newrect.y += move_px;
|
||||
break;
|
||||
}
|
||||
|
||||
cmd_output->needs_tree_render = floating_reposition(current->con->parent, newrect);
|
||||
} else {
|
||||
tree_move(current->con, direction);
|
||||
cmd_output->needs_tree_render = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* The move command should not disturb focus. con_exists is called because
|
||||
* tree_move calls tree_flatten. */
|
||||
if (focused != initially_focused && con_exists(initially_focused)) {
|
||||
con_activate(initially_focused);
|
||||
}
|
||||
|
||||
// XXX: default reply for now, make this a better reply
|
||||
ysuccess(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of 'layout default|stacked|stacking|tabbed|splitv|splith'.
|
||||
*
|
||||
*/
|
||||
void cmd_layout(I3_CMD, const char *layout_str) {
|
||||
HANDLE_EMPTY_MATCH;
|
||||
|
||||
layout_t layout;
|
||||
if (!layout_from_name(layout_str, &layout)) {
|
||||
yerror("Unknown layout \"%s\", this is a mismatch between code and parser spec.", layout_str);
|
||||
return;
|
||||
}
|
||||
|
||||
DLOG("changing layout to %s (%d)\n", layout_str, layout);
|
||||
|
||||
owindow *current;
|
||||
TAILQ_FOREACH (current, &owindows, owindows) {
|
||||
if (con_is_docked(current->con)) {
|
||||
ELOG("cannot change layout of a docked container, skipping it.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
DLOG("matching: %p / %s\n", current->con, current->con->name);
|
||||
con_set_layout(current->con, layout);
|
||||
}
|
||||
|
||||
cmd_output->needs_tree_render = true;
|
||||
// XXX: default reply for now, make this a better reply
|
||||
ysuccess(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of 'layout toggle [all|split]'.
|
||||
*
|
||||
*/
|
||||
void cmd_layout_toggle(I3_CMD, const char *toggle_mode) {
|
||||
owindow *current;
|
||||
|
||||
if (toggle_mode == NULL)
|
||||
toggle_mode = "default";
|
||||
|
||||
DLOG("toggling layout (mode = %s)\n", toggle_mode);
|
||||
|
||||
/* check if the match is empty, not if the result is empty */
|
||||
if (match_is_empty(current_match))
|
||||
con_toggle_layout(focused, toggle_mode);
|
||||
else {
|
||||
TAILQ_FOREACH (current, &owindows, owindows) {
|
||||
DLOG("matching: %p / %s\n", current->con, current->con->name);
|
||||
con_toggle_layout(current->con, toggle_mode);
|
||||
}
|
||||
}
|
||||
|
||||
cmd_output->needs_tree_render = true;
|
||||
// XXX: default reply for now, make this a better reply
|
||||
ysuccess(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of 'exit'.
|
||||
*
|
||||
|
@ -1858,110 +1784,114 @@ void cmd_title_format(I3_CMD, const char *format) {
|
|||
* Implementation of 'rename workspace [<name>] to <name>'
|
||||
*
|
||||
*/
|
||||
void cmd_rename_workspace(I3_CMD, const char *old_name, const char *new_name) {
|
||||
if (strncasecmp(new_name, "__", strlen("__")) == 0) {
|
||||
yerror("Cannot rename workspace to \"%s\": names starting with __ are i3-internal.", new_name);
|
||||
return;
|
||||
}
|
||||
if (old_name) {
|
||||
LOG("Renaming workspace \"%s\" to \"%s\"\n", old_name, new_name);
|
||||
} else {
|
||||
LOG("Renaming current workspace to \"%s\"\n", new_name);
|
||||
SCM guile_rename_workspace(SCM g_old_name, SCM g_new_name) {
|
||||
char * old_name = scm_to_locale_string(g_old_name);
|
||||
char * new_name = scm_to_locale_string(g_new_name);
|
||||
|
||||
if (strncasecmp(new_name, "__", strlen("__")) == 0) {
|
||||
/* yerror("Cannot rename workspace to \"%s\": names starting with __ are i3-internal.", new_name); */
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
// FIXME
|
||||
if (old_name) {
|
||||
LOG("Renaming workspace \"%s\" to \"%s\"\n", old_name, new_name);
|
||||
} else {
|
||||
LOG("Renaming current workspace to \"%s\"\n", new_name);
|
||||
}
|
||||
|
||||
Con *workspace;
|
||||
if (old_name) {
|
||||
workspace = get_existing_workspace_by_name(old_name);
|
||||
} else {
|
||||
workspace = con_get_workspace(focused);
|
||||
old_name = workspace->name;
|
||||
}
|
||||
|
||||
if (!workspace) {
|
||||
/* yerror("Old workspace \"%s\" not found", old_name); */
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
|
||||
Con *check_dest = get_existing_workspace_by_name(new_name);
|
||||
|
||||
/* If check_dest == workspace, the user might be changing the case of the
|
||||
* workspace, or it might just be a no-op. */
|
||||
if (check_dest != NULL && check_dest != workspace) {
|
||||
/* yerror("New workspace \"%s\" already exists", new_name); */
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
|
||||
/* Change the name and try to parse it as a number. */
|
||||
/* old_name might refer to workspace->name, so copy it before free()ing */
|
||||
char *old_name_copy = sstrdup(old_name);
|
||||
FREE(workspace->name);
|
||||
workspace->name = sstrdup(new_name);
|
||||
|
||||
workspace->num = ws_name_to_number(new_name);
|
||||
LOG("num = %d\n", workspace->num);
|
||||
|
||||
/* By re-attaching, the sort order will be correct afterwards. */
|
||||
Con *previously_focused = focused;
|
||||
Con *previously_focused_content = focused->type == CT_WORKSPACE ? focused->parent : NULL;
|
||||
Con *parent = workspace->parent;
|
||||
con_detach(workspace);
|
||||
con_attach(workspace, parent, false);
|
||||
ipc_send_workspace_event("rename", workspace, NULL);
|
||||
|
||||
/* Move the workspace to the correct output if it has an assignment */
|
||||
struct Workspace_Assignment *assignment = NULL;
|
||||
TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) {
|
||||
if (assignment->output == NULL)
|
||||
continue;
|
||||
if (strcmp(assignment->name, workspace->name) != 0 && (!name_is_digits(assignment->name) || ws_name_to_number(assignment->name) != workspace->num)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Con *workspace;
|
||||
if (old_name) {
|
||||
workspace = get_existing_workspace_by_name(old_name);
|
||||
} else {
|
||||
workspace = con_get_workspace(focused);
|
||||
old_name = workspace->name;
|
||||
Output *target_output = get_output_by_name(assignment->output, true);
|
||||
if (!target_output) {
|
||||
LOG("Could not get output named \"%s\"\n", assignment->output);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!workspace) {
|
||||
yerror("Old workspace \"%s\" not found", old_name);
|
||||
return;
|
||||
if (!output_triggers_assignment(target_output, assignment)) {
|
||||
continue;
|
||||
}
|
||||
workspace_move_to_output(workspace, target_output);
|
||||
|
||||
Con *check_dest = get_existing_workspace_by_name(new_name);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If check_dest == workspace, the user might be changing the case of the
|
||||
* workspace, or it might just be a no-op. */
|
||||
if (check_dest != NULL && check_dest != workspace) {
|
||||
yerror("New workspace \"%s\" already exists", new_name);
|
||||
return;
|
||||
}
|
||||
bool can_restore_focus = previously_focused != NULL;
|
||||
/* NB: If previously_focused is a workspace we can't work directly with it
|
||||
* since it might have been cleaned up by workspace_show() already,
|
||||
* depending on the focus order/number of other workspaces on the output.
|
||||
* Instead, we loop through the available workspaces and only focus
|
||||
* previously_focused if we still find it. */
|
||||
if (previously_focused_content) {
|
||||
Con *workspace = NULL;
|
||||
GREP_FIRST(workspace, previously_focused_content, child == previously_focused);
|
||||
can_restore_focus &= (workspace != NULL);
|
||||
}
|
||||
|
||||
/* Change the name and try to parse it as a number. */
|
||||
/* old_name might refer to workspace->name, so copy it before free()ing */
|
||||
char *old_name_copy = sstrdup(old_name);
|
||||
FREE(workspace->name);
|
||||
workspace->name = sstrdup(new_name);
|
||||
if (can_restore_focus) {
|
||||
/* Restore the previous focus since con_attach messes with the focus. */
|
||||
workspace_show(con_get_workspace(previously_focused));
|
||||
con_focus(previously_focused);
|
||||
}
|
||||
|
||||
workspace->num = ws_name_to_number(new_name);
|
||||
LOG("num = %d\n", workspace->num);
|
||||
/* Let back-and-forth work after renaming the previous workspace.
|
||||
* See #3694. */
|
||||
if (previous_workspace_name && !strcmp(previous_workspace_name, old_name_copy)) {
|
||||
FREE(previous_workspace_name);
|
||||
previous_workspace_name = sstrdup(new_name);
|
||||
}
|
||||
|
||||
/* By re-attaching, the sort order will be correct afterwards. */
|
||||
Con *previously_focused = focused;
|
||||
Con *previously_focused_content = focused->type == CT_WORKSPACE ? focused->parent : NULL;
|
||||
Con *parent = workspace->parent;
|
||||
con_detach(workspace);
|
||||
con_attach(workspace, parent, false);
|
||||
ipc_send_workspace_event("rename", workspace, NULL);
|
||||
tree_render();
|
||||
|
||||
/* Move the workspace to the correct output if it has an assignment */
|
||||
struct Workspace_Assignment *assignment = NULL;
|
||||
TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) {
|
||||
if (assignment->output == NULL)
|
||||
continue;
|
||||
if (strcmp(assignment->name, workspace->name) != 0 && (!name_is_digits(assignment->name) || ws_name_to_number(assignment->name) != workspace->num)) {
|
||||
continue;
|
||||
}
|
||||
ewmh_update_desktop_properties();
|
||||
|
||||
Output *target_output = get_output_by_name(assignment->output, true);
|
||||
if (!target_output) {
|
||||
LOG("Could not get output named \"%s\"\n", assignment->output);
|
||||
continue;
|
||||
}
|
||||
if (!output_triggers_assignment(target_output, assignment)) {
|
||||
continue;
|
||||
}
|
||||
workspace_move_to_output(workspace, target_output);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
bool can_restore_focus = previously_focused != NULL;
|
||||
/* NB: If previously_focused is a workspace we can't work directly with it
|
||||
* since it might have been cleaned up by workspace_show() already,
|
||||
* depending on the focus order/number of other workspaces on the output.
|
||||
* Instead, we loop through the available workspaces and only focus
|
||||
* previously_focused if we still find it. */
|
||||
if (previously_focused_content) {
|
||||
Con *workspace = NULL;
|
||||
GREP_FIRST(workspace, previously_focused_content, child == previously_focused);
|
||||
can_restore_focus &= (workspace != NULL);
|
||||
}
|
||||
|
||||
if (can_restore_focus) {
|
||||
/* Restore the previous focus since con_attach messes with the focus. */
|
||||
workspace_show(con_get_workspace(previously_focused));
|
||||
con_focus(previously_focused);
|
||||
}
|
||||
|
||||
/* Let back-and-forth work after renaming the previous workspace.
|
||||
* See #3694. */
|
||||
if (previous_workspace_name && !strcmp(previous_workspace_name, old_name_copy)) {
|
||||
FREE(previous_workspace_name);
|
||||
previous_workspace_name = sstrdup(new_name);
|
||||
}
|
||||
|
||||
cmd_output->needs_tree_render = true;
|
||||
ysuccess(true);
|
||||
|
||||
ewmh_update_desktop_properties();
|
||||
|
||||
startup_sequence_rename_workspace(old_name_copy, new_name);
|
||||
free(old_name_copy);
|
||||
startup_sequence_rename_workspace(old_name_copy, new_name);
|
||||
free(old_name_copy);
|
||||
return SCM_BOOL_T;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2221,13 +2151,27 @@ SCM guile_focus_direction(SCM g_direction) {
|
|||
char * direction_str = scm_to_locale_string(g_direction);
|
||||
Con * con;
|
||||
owindow * ow;
|
||||
while (!TAILQ_EMPTY(&owindows)) {
|
||||
ow = TAILQ_FIRST(&owindows);
|
||||
TAILQ_REMOVE(&owindows, ow, owindows);
|
||||
free(ow);
|
||||
}
|
||||
int count = 0;
|
||||
owindow *current;
|
||||
|
||||
/* if (current_match->error != NULL) { */
|
||||
/* /\* yerror("Invalid match: %s", current_match->error); *\/ */
|
||||
/* return SCM_BOOL_F; */
|
||||
/* } */
|
||||
|
||||
/* if (match_is_empty(current_match)) { */
|
||||
while (!TAILQ_EMPTY(&owindows)) {
|
||||
ow = TAILQ_FIRST(&owindows);
|
||||
TAILQ_REMOVE(&owindows, ow, owindows);
|
||||
free(ow);
|
||||
}
|
||||
ow = smalloc(sizeof(owindow));
|
||||
ow->con = focused;
|
||||
TAILQ_INIT(&owindows);
|
||||
TAILQ_INSERT_TAIL(&owindows, ow, owindows);
|
||||
/* } */
|
||||
|
||||
|
||||
TAILQ_FOREACH (current, &owindows, owindows) {
|
||||
count++;
|
||||
}
|
||||
|
@ -2236,7 +2180,6 @@ SCM guile_focus_direction(SCM g_direction) {
|
|||
"while only exactly one container can be focused at a time.\n",
|
||||
count);
|
||||
}
|
||||
|
||||
direction_t direction;
|
||||
position_t position;
|
||||
bool auto_direction = true;
|
||||
|
@ -2264,3 +2207,112 @@ SCM guile_focus_direction(SCM g_direction) {
|
|||
tree_render();
|
||||
return SCM_BOOL_T;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of 'move <direction> [<pixels> [px]]'.
|
||||
*
|
||||
*/
|
||||
void cmd_move_direction(I3_CMD, const char *direction_str, long move_px) {
|
||||
owindow *current;
|
||||
HANDLE_EMPTY_MATCH;
|
||||
|
||||
Con *initially_focused = focused;
|
||||
direction_t direction = parse_direction(direction_str);
|
||||
|
||||
TAILQ_FOREACH (current, &owindows, owindows) {
|
||||
DLOG("moving in direction %s, px %ld\n", direction_str, move_px);
|
||||
if (con_is_floating(current->con)) {
|
||||
DLOG("floating move with %ld pixels\n", move_px);
|
||||
Rect newrect = current->con->parent->rect;
|
||||
|
||||
switch (direction) {
|
||||
case D_LEFT:
|
||||
newrect.x -= move_px;
|
||||
break;
|
||||
case D_RIGHT:
|
||||
newrect.x += move_px;
|
||||
break;
|
||||
case D_UP:
|
||||
newrect.y -= move_px;
|
||||
break;
|
||||
case D_DOWN:
|
||||
newrect.y += move_px;
|
||||
break;
|
||||
}
|
||||
|
||||
cmd_output->needs_tree_render = floating_reposition(current->con->parent, newrect);
|
||||
} else {
|
||||
tree_move(current->con, direction);
|
||||
cmd_output->needs_tree_render = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* The move command should not disturb focus. con_exists is called because
|
||||
* tree_move calls tree_flatten. */
|
||||
if (focused != initially_focused && con_exists(initially_focused)) {
|
||||
con_activate(initially_focused);
|
||||
}
|
||||
|
||||
// XXX: default reply for now, make this a better reply
|
||||
ysuccess(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of 'layout default|stacked|stacking|tabbed|splitv|splith'.
|
||||
*
|
||||
*/
|
||||
SCM guile_layout(SCM g_layout) {
|
||||
owindow *ow;
|
||||
|
||||
while (!TAILQ_EMPTY(&owindows)) {
|
||||
ow = TAILQ_FIRST(&owindows);
|
||||
TAILQ_REMOVE(&owindows, ow, owindows);
|
||||
free(ow);
|
||||
}
|
||||
ow = smalloc(sizeof(owindow));
|
||||
ow->con = focused;
|
||||
TAILQ_INIT(&owindows);
|
||||
TAILQ_INSERT_TAIL(&owindows, ow, owindows);
|
||||
|
||||
|
||||
char * layout_str = scm_to_locale_string(g_layout);
|
||||
layout_t layout;
|
||||
if (!layout_from_name(layout_str, &layout)) {
|
||||
/* yerror("Unknown layout \"%s\", this is a mismatch between code and parser spec.", layout_str); */
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
|
||||
DLOG("changing layout to %s (%d)\n", layout_str, layout);
|
||||
|
||||
owindow *current;
|
||||
TAILQ_FOREACH (current, &owindows, owindows) {
|
||||
if (con_is_docked(current->con)) {
|
||||
ELOG("cannot change layout of a docked container, skipping it.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
DLOG("matching: %p / %s\n", current->con, current->con->name);
|
||||
con_set_layout(current->con, layout);
|
||||
}
|
||||
|
||||
tree_render();
|
||||
return SCM_BOOL_T;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of 'layout toggle [all|split]'.
|
||||
*
|
||||
*/
|
||||
SCM guile_layout_toggle(SCM g_toggle_mode) {
|
||||
owindow *current;
|
||||
|
||||
char * toggle_mode = scm_to_locale_string(g_toggle_mode);
|
||||
|
||||
DLOG("toggling layout (mode = %s)\n", toggle_mode);
|
||||
|
||||
/* check if the match is empty, not if the result is empty */
|
||||
con_toggle_layout(focused, toggle_mode);
|
||||
|
||||
tree_render();
|
||||
return SCM_BOOL_T;
|
||||
}
|
||||
|
|
|
@ -337,6 +337,11 @@ register_functions (void* data) {
|
|||
scm_c_define_gsubr ("kill", 0, 0, 0, &guile_kill);
|
||||
scm_c_define_gsubr ("split", 1, 0, 0, &guile_split);
|
||||
scm_c_define_gsubr ("focus-direction", 1, 0, 0, &guile_focus_direction);
|
||||
scm_c_define_gsubr ("layout", 1, 0, 0, &guile_layout);
|
||||
scm_c_define_gsubr ("toggle-layout", 1, 0, 0, &guile_layout_toggle);
|
||||
scm_c_define_gsubr ("move-to-workspace", 1, 0, 0, &guile_move_con_to_workspace);
|
||||
|
||||
scm_c_define_gsubr ("rename-workspace", 2, 0, 0, &guile_rename_workspace);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue