X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcommands.c;h=44b910ec40ba67960d008e1b069ff0cd30f59100;hb=9940571069336e9b9a60dc2f95ea3a329a3c7c5e;hp=f5f8d05c7c9a1befe8b9ea4112edc93dcdca8aed;hpb=c263bb3d2ae73fbec19640934286bd369a5fff23;p=i3%2Fi3 diff --git a/src/commands.c b/src/commands.c index f5f8d05c..44b910ec 100644 --- a/src/commands.c +++ b/src/commands.c @@ -4,7 +4,7 @@ * vim:ts=4:sw=4:expandtab * * i3 - an improved dynamic tiling window manager - * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE) + * © 2009 Michael Stapelberg and contributors (see also: LICENSE) * * commands.c: all command functions (see commands_parser.c) * @@ -335,7 +335,7 @@ void cmd_criteria_add(I3_CMD, char *ctype, char *cvalue) { if (strcmp(ctype, "con_id") == 0) { char *end; - long parsed = strtol(cvalue, &end, 10); + long parsed = strtol(cvalue, &end, 0); if (parsed == LONG_MIN || parsed == LONG_MAX || parsed < 0 || @@ -350,7 +350,7 @@ void cmd_criteria_add(I3_CMD, char *ctype, char *cvalue) { if (strcmp(ctype, "id") == 0) { char *end; - long parsed = strtol(cvalue, &end, 10); + long parsed = strtol(cvalue, &end, 0); if (parsed == LONG_MIN || parsed == LONG_MAX || parsed < 0 || @@ -363,6 +363,31 @@ void cmd_criteria_add(I3_CMD, char *ctype, char *cvalue) { return; } + if (strcmp(ctype, "window_type") == 0) { + if (strcasecmp(cvalue, "normal") == 0) + current_match->window_type = A__NET_WM_WINDOW_TYPE_NORMAL; + else if (strcasecmp(cvalue, "dialog") == 0) + current_match->window_type = A__NET_WM_WINDOW_TYPE_DIALOG; + else if (strcasecmp(cvalue, "utility") == 0) + current_match->window_type = A__NET_WM_WINDOW_TYPE_UTILITY; + else if (strcasecmp(cvalue, "toolbar") == 0) + current_match->window_type = A__NET_WM_WINDOW_TYPE_TOOLBAR; + else if (strcasecmp(cvalue, "splash") == 0) + current_match->window_type = A__NET_WM_WINDOW_TYPE_SPLASH; + else if (strcasecmp(cvalue, "menu") == 0) + current_match->window_type = A__NET_WM_WINDOW_TYPE_MENU; + else if (strcasecmp(cvalue, "dropdown_menu") == 0) + current_match->window_type = A__NET_WM_WINDOW_TYPE_DROPDOWN_MENU; + else if (strcasecmp(cvalue, "popup_menu") == 0) + current_match->window_type = A__NET_WM_WINDOW_TYPE_POPUP_MENU; + else if (strcasecmp(cvalue, "tooltip") == 0) + current_match->window_type = A__NET_WM_WINDOW_TYPE_TOOLTIP; + else + ELOG("unknown window_type value \"%s\"\n", cvalue); + + return; + } + if (strcmp(ctype, "con_mark") == 0) { current_match->mark = regex_new(cvalue); return; @@ -494,27 +519,7 @@ void cmd_move_con_to_workspace_name(I3_CMD, char *name) { LOG("should move window to workspace %s\n", name); /* get the workspace */ - Con *ws = NULL; - Con *output = NULL; - - /* first look for a workspace with this name */ - TAILQ_FOREACH(output, &(croot->nodes_head), nodes) { - GREP_FIRST(ws, output_get_content(output), !strcasecmp(child->name, name)); - } - - /* if the name is plain digits, we interpret this as a "workspace number" - * command */ - if (!ws && name_is_digits(name)) { - long parsed_num = ws_name_to_number(name); - TAILQ_FOREACH(output, &(croot->nodes_head), nodes) { - GREP_FIRST(ws, output_get_content(output), - child->num == parsed_num); - } - } - - /* if no workspace was found, make a new one */ - if (!ws) - ws = workspace_get(name, NULL); + Con *ws = workspace_get(name, NULL); ws = maybe_auto_back_and_forth_workspace(ws); @@ -811,7 +816,7 @@ void cmd_resize(I3_CMD, char *way, char *direction, char *resize_px, char *resiz } /* - * Implementation of 'border normal|none|1pixel|toggle|pixel'. + * Implementation of 'border normal|pixel []', 'border none|1pixel|toggle'. * */ void cmd_border(I3_CMD, char *border_style_str, char *border_width) { @@ -1049,30 +1054,7 @@ void cmd_workspace_name(I3_CMD, char *name) { DLOG("should switch to workspace %s\n", name); if (maybe_back_and_forth(cmd_output, name)) return; - - Con *ws = NULL; - Con *output = NULL; - - /* first look for a workspace with this name */ - TAILQ_FOREACH(output, &(croot->nodes_head), nodes) { - GREP_FIRST(ws, output_get_content(output), !strcasecmp(child->name, name)); - } - - /* if the name is only digits, we interpret this as a "workspace number" - * command */ - if (!ws && name_is_digits(name)) { - long parsed_num = ws_name_to_number(name); - TAILQ_FOREACH(output, &(croot->nodes_head), nodes) { - GREP_FIRST(ws, output_get_content(output), - child->num == parsed_num); - } - } - - /* if no workspace was found, make a new one */ - if (!ws) - ws = workspace_get(name, NULL); - - workspace_show(ws); + workspace_show_by_name(name); cmd_output->needs_tree_render = true; // XXX: default reply for now, make this a better reply @@ -1080,28 +1062,48 @@ void cmd_workspace_name(I3_CMD, char *name) { } /* - * Implementation of 'mark ' + * Implementation of 'mark [--toggle] ' * */ -void cmd_mark(I3_CMD, char *mark) { - DLOG("Clearing all windows which have that mark first\n"); +void cmd_mark(I3_CMD, char *mark, char *toggle) { + HANDLE_EMPTY_MATCH; - Con *con; - TAILQ_FOREACH(con, &all_cons, all_cons) { - if (con->mark && strcmp(con->mark, mark) == 0) - FREE(con->mark); + owindow *current = TAILQ_FIRST(&owindows); + if (current == NULL) { + ysuccess(false); + return; } - DLOG("marking window with str %s\n", mark); - owindow *current; - - HANDLE_EMPTY_MATCH; + /* Marks must be unique, i.e., no two windows must have the same mark. */ + if (current != TAILQ_LAST(&owindows, owindows_head)) { + yerror("A mark must not be put onto more than one window"); + return; + } - TAILQ_FOREACH(current, &owindows, owindows) { - DLOG("matching: %p / %s\n", current->con, current->con->name); + DLOG("matching: %p / %s\n", current->con, current->con->name); + current->con->mark_changed = true; + if (toggle != NULL && current->con->mark && strcmp(current->con->mark, mark) == 0) { + DLOG("removing window mark %s\n", mark); + FREE(current->con->mark); + } else { + DLOG("marking window with str %s\n", mark); + FREE(current->con->mark); current->con->mark = sstrdup(mark); } + DLOG("Clearing all non-matched windows with this mark\n"); + Con *con; + TAILQ_FOREACH(con, &all_cons, all_cons) { + /* Skip matched window, we took care of it already. */ + if (current->con == con) + continue; + + if (con->mark && strcmp(con->mark, mark) == 0) { + FREE(con->mark); + con->mark_changed = true; + } + } + cmd_output->needs_tree_render = true; // XXX: default reply for now, make this a better reply ysuccess(true); @@ -1115,14 +1117,18 @@ void cmd_unmark(I3_CMD, char *mark) { if (mark == NULL) { Con *con; TAILQ_FOREACH(con, &all_cons, all_cons) { + if (con->mark == NULL) + continue; + FREE(con->mark); + con->mark_changed = true; } DLOG("removed all window marks"); } else { - Con *con; - TAILQ_FOREACH(con, &all_cons, all_cons) { - if (con->mark && strcmp(con->mark, mark) == 0) - FREE(con->mark); + Con *con = con_by_mark(mark); + if (con != NULL) { + FREE(con->mark); + con->mark_changed = true; } DLOG("removed window mark %s\n", mark); } @@ -1186,6 +1192,26 @@ void cmd_move_con_to_output(I3_CMD, char *name) { ysuccess(true); } +/* + * Implementation of 'move [container|window] [to] mark '. + * + */ +void cmd_move_con_to_mark(I3_CMD, char *mark) { + DLOG("moving window to mark \"%s\"\n", mark); + + HANDLE_EMPTY_MATCH; + + bool result = true; + owindow *current; + TAILQ_FOREACH(current, &owindows, owindows) { + DLOG("moving matched window %p / %s to mark \"%s\"\n", current->con, current->con->name, mark); + result &= con_move_to_mark(current->con, mark); + } + + cmd_output->needs_tree_render = true; + ysuccess(result); +} + /* * Implementation of 'floating enable|disable|toggle' * @@ -1789,31 +1815,48 @@ void cmd_move_window_to_center(I3_CMD, char *method) { } if (strcmp(method, "absolute") == 0) { - Rect *rect = &focused->parent->rect; - DLOG("moving to absolute center\n"); - rect->x = croot->rect.width / 2 - rect->width / 2; - rect->y = croot->rect.height / 2 - rect->height / 2; + floating_center(focused->parent, croot->rect); floating_maybe_reassign_ws(focused->parent); cmd_output->needs_tree_render = true; } if (strcmp(method, "position") == 0) { - Rect *wsrect = &con_get_workspace(focused)->rect; - Rect newrect = focused->parent->rect; - DLOG("moving to center\n"); - newrect.x = wsrect->width / 2 - newrect.width / 2; - newrect.y = wsrect->height / 2 - newrect.height / 2; + floating_center(focused->parent, con_get_workspace(focused)->rect); - floating_reposition(focused->parent, newrect); + cmd_output->needs_tree_render = true; } // XXX: default reply for now, make this a better reply ysuccess(true); } +/* + * Implementation of 'move [window|container] [to] position mouse' + * + */ +void cmd_move_window_to_mouse(I3_CMD) { + HANDLE_EMPTY_MATCH; + + owindow *current; + TAILQ_FOREACH(current, &owindows, owindows) { + Con *floating_con = con_inside_floating(current->con); + if (floating_con == NULL) { + DLOG("con %p / %s is not floating, cannot move it to the mouse position.\n", + current->con, current->con->name); + continue; + } + + DLOG("moving floating container %p / %s to cursor position\n", floating_con, floating_con->name); + floating_move_to_pointer(floating_con); + } + + cmd_output->needs_tree_render = true; + ysuccess(true); +} + /* * Implementation of 'move scratchpad'. * @@ -1879,6 +1922,7 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name) { !strcasecmp(child->name, old_name)); } else { workspace = con_get_workspace(focused); + old_name = workspace->name; } if (!workspace) { @@ -1914,13 +1958,15 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name) { 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)) { - + if (strcmp(assignment->name, workspace->name) != 0 && (!name_is_digits(assignment->name) || ws_name_to_number(assignment->name) != workspace->num)) { continue; } workspace_move_to_output(workspace, assignment->output); + + if (previously_focused) + workspace_show(con_get_workspace(previously_focused)); + break; } @@ -1934,6 +1980,8 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name) { ewmh_update_desktop_names(); ewmh_update_desktop_viewport(); ewmh_update_current_desktop(); + + startup_sequence_rename_workspace(old_name, new_name); } /*