diff options
Diffstat (limited to 'sway/commands')
-rw-r--r-- | sway/commands/bind.c | 9 | ||||
-rw-r--r-- | sway/commands/exec_always.c | 28 | ||||
-rw-r--r-- | sway/commands/focus.c | 18 | ||||
-rw-r--r-- | sway/commands/font.c | 27 | ||||
-rw-r--r-- | sway/commands/gesture.c | 166 | ||||
-rw-r--r-- | sway/commands/input.c | 1 | ||||
-rw-r--r-- | sway/commands/input/dwtp.c | 25 | ||||
-rw-r--r-- | sway/commands/input/xkb_switch_layout.c | 36 | ||||
-rw-r--r-- | sway/commands/mode.c | 3 | ||||
-rw-r--r-- | sway/commands/move.c | 19 | ||||
-rw-r--r-- | sway/commands/output.c | 2 | ||||
-rw-r--r-- | sway/commands/output/background.c | 12 | ||||
-rw-r--r-- | sway/commands/output/dpms.c | 45 | ||||
-rw-r--r-- | sway/commands/output/power.c | 43 | ||||
-rw-r--r-- | sway/commands/output/unplug.c | 54 | ||||
-rw-r--r-- | sway/commands/rename.c | 3 | ||||
-rw-r--r-- | sway/commands/seat/cursor.c | 4 |
17 files changed, 417 insertions, 78 deletions
diff --git a/sway/commands/bind.c b/sway/commands/bind.c index 25be415e..c0b383db 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c @@ -47,7 +47,7 @@ static bool binding_switch_compare(struct sway_switch_binding *binding_a, if (binding_a->type != binding_b->type) { return false; } - if (binding_a->state != binding_b->state) { + if (binding_a->trigger != binding_b->trigger) { return false; } if ((binding_a->flags & BINDING_LOCKED) != @@ -372,6 +372,7 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv, strlen("--input-device=")) == 0) { free(binding->input); binding->input = strdup(argv[0] + strlen("--input-device=")); + strip_quotes(binding->input); } else if (strcmp("--no-warn", argv[0]) == 0) { warn = false; } else if (strcmp("--no-repeat", argv[0]) == 0) { @@ -551,11 +552,11 @@ struct cmd_results *cmd_bind_or_unbind_switch(int argc, char **argv, "unknown switch %s)", bindtype, split->items[0]); } if (strcmp(split->items[1], "on") == 0) { - binding->state = WLR_SWITCH_STATE_ON; + binding->trigger = SWAY_SWITCH_TRIGGER_ON; } else if (strcmp(split->items[1], "off") == 0) { - binding->state = WLR_SWITCH_STATE_OFF; + binding->trigger = SWAY_SWITCH_TRIGGER_OFF; } else if (strcmp(split->items[1], "toggle") == 0) { - binding->state = WLR_SWITCH_STATE_TOGGLE; + binding->trigger = SWAY_SWITCH_TRIGGER_TOGGLE; } else { free_switch_binding(binding); return cmd_results_new(CMD_FAILURE, diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c index b35065c1..e6b09e64 100644 --- a/sway/commands/exec_always.c +++ b/sway/commands/exec_always.c @@ -8,6 +8,8 @@ #include "sway/commands.h" #include "sway/config.h" #include "sway/server.h" +#include "sway/desktop/launcher.h" +#include "sway/server.h" #include "sway/tree/container.h" #include "sway/tree/root.h" #include "sway/tree/workspace.h" @@ -25,11 +27,22 @@ struct cmd_results *cmd_exec_validate(int argc, char **argv) { return error; } +static void export_xdga_token(struct launcher_ctx *ctx) { + const char *token = launcher_ctx_get_token_name(ctx); + setenv("XDG_ACTIVATION_TOKEN", token, 1); +} + +static void export_startup_id(struct launcher_ctx *ctx) { + const char *token = launcher_ctx_get_token_name(ctx); + setenv("DESKTOP_STARTUP_ID", token, 1); +} + struct cmd_results *cmd_exec_process(int argc, char **argv) { struct cmd_results *error = NULL; char *cmd = NULL; + bool no_startup_id = false; if (strcmp(argv[0], "--no-startup-id") == 0) { - sway_log(SWAY_INFO, "exec switch '--no-startup-id' not supported, ignored."); + no_startup_id = true; --argc; ++argv; if ((error = checkarg(argc, argv[-1], EXPECTED_AT_LEAST, 1))) { return error; @@ -51,6 +64,7 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) { } pid_t pid, child; + struct launcher_ctx *ctx = launcher_ctx_create(); // Fork process if ((pid = fork()) == 0) { // Fork child process again @@ -63,6 +77,12 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) { close(fd[0]); if ((child = fork()) == 0) { close(fd[1]); + if (ctx) { + export_xdga_token(ctx); + } + if (ctx && !no_startup_id) { + export_startup_id(ctx); + } execlp("sh", "sh", "-c", cmd, (void *)NULL); sway_log_errno(SWAY_ERROR, "execlp failed"); _exit(1); @@ -90,8 +110,12 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) { waitpid(pid, NULL, 0); if (child > 0) { sway_log(SWAY_DEBUG, "Child process created with pid %d", child); - root_record_workspace_pid(child); + if (ctx != NULL) { + sway_log(SWAY_DEBUG, "Recording workspace for process %d", child); + ctx->pid = child; + } } else { + launcher_ctx_destroy(ctx); return cmd_results_new(CMD_FAILURE, "Second fork() failed"); } diff --git a/sway/commands/focus.c b/sway/commands/focus.c index b8d28480..facd82de 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c @@ -54,7 +54,7 @@ static bool get_direction_from_next_prev(struct sway_container *container, } else { return false; } - + return true; } @@ -285,7 +285,7 @@ static struct cmd_results *focus_mode(struct sway_workspace *ws, } } else { return cmd_results_new(CMD_FAILURE, - "Failed to find a %s container in workspace", + "Failed to find a %s container in workspace.", floating ? "floating" : "tiling"); } return cmd_results_new(CMD_SUCCESS, NULL); @@ -295,7 +295,7 @@ static struct cmd_results *focus_output(struct sway_seat *seat, int argc, char **argv) { if (!argc) { return cmd_results_new(CMD_INVALID, - "Expected 'focus output <direction|name>'"); + "Expected 'focus output <direction|name>'."); } char *identifier = join_args(argv, argc); struct sway_output *output = output_by_name_or_id(identifier); @@ -305,13 +305,13 @@ static struct cmd_results *focus_output(struct sway_seat *seat, if (!parse_direction(identifier, &direction)) { free(identifier); return cmd_results_new(CMD_INVALID, - "There is no output with that name"); + "There is no output with that name."); } struct sway_workspace *ws = seat_get_focused_workspace(seat); if (!ws) { free(identifier); return cmd_results_new(CMD_FAILURE, - "No focused workspace to base directions off of"); + "No focused workspace to base directions off of."); } output = output_get_in_direction(ws->output, direction); @@ -375,10 +375,14 @@ struct cmd_results *cmd_focus(int argc, char **argv) { struct sway_seat *seat = config->handler_context.seat; if (node->type < N_WORKSPACE) { return cmd_results_new(CMD_FAILURE, - "Command 'focus' cannot be used above the workspace level"); + "Command 'focus' cannot be used above the workspace level."); } - if (argc == 0 && container) { + if (argc == 0) { + if (!container) { + return cmd_results_new(CMD_FAILURE, "No container to focus was specified."); + } + if (container_is_scratchpad_hidden_or_child(container)) { root_scratchpad_show(container); } diff --git a/sway/commands/font.c b/sway/commands/font.c index cea720f5..74bb6b9f 100644 --- a/sway/commands/font.c +++ b/sway/commands/font.c @@ -4,6 +4,7 @@ #include "sway/config.h" #include "log.h" #include "stringop.h" +#include <pango/pangocairo.h> struct cmd_results *cmd_font(int argc, char **argv) { struct cmd_results *error = NULL; @@ -16,12 +17,34 @@ struct cmd_results *cmd_font(int argc, char **argv) { if (strncmp(font, "pango:", 6) == 0) { config->pango_markup = true; config->font = strdup(font + 6); + free(font); } else { config->pango_markup = false; - config->font = strdup(font); + config->font = font; } - free(font); + // Parse the font early so we can reject it if it's not valid for pango. + // Also avoids re-parsing each time we render text. + PangoFontDescription *font_description = pango_font_description_from_string(config->font); + + const char *family = pango_font_description_get_family(font_description); + if (family == NULL) { + pango_font_description_free(font_description); + return cmd_results_new(CMD_FAILURE, "Invalid font family."); + } + + const gint size = pango_font_description_get_size(font_description); + if (size == 0) { + pango_font_description_free(font_description); + return cmd_results_new(CMD_FAILURE, "Invalid font size."); + } + + if (config->font_description != NULL) { + pango_font_description_free(config->font_description); + } + + config->font_description = font_description; config_update_font_height(); + return cmd_results_new(CMD_SUCCESS, NULL); } diff --git a/sway/commands/gesture.c b/sway/commands/gesture.c new file mode 100644 index 00000000..d4442cc3 --- /dev/null +++ b/sway/commands/gesture.c @@ -0,0 +1,166 @@ +#define _POSIX_C_SOURCE 200809L +#include "sway/config.h" + +#include "gesture.h" +#include "log.h" +#include "stringop.h" +#include "sway/commands.h" + +void free_gesture_binding(struct sway_gesture_binding *binding) { + if (!binding) { + return; + } + free(binding->input); + free(binding->command); + free(binding); +} + +/** + * Returns true if the bindings have the same gesture type, direction, etc + */ +static bool binding_gesture_equal(struct sway_gesture_binding *binding_a, + struct sway_gesture_binding *binding_b) { + if (strcmp(binding_a->input, binding_b->input) != 0) { + return false; + } + + if (!gesture_equal(&binding_a->gesture, &binding_b->gesture)) { + return false; + } + + if ((binding_a->flags & BINDING_EXACT) != + (binding_b->flags & BINDING_EXACT)) { + return false; + } + return true; +} + +/** + * Add gesture binding to config + */ +static struct cmd_results *gesture_binding_add( + struct sway_gesture_binding *binding, + const char *gesturecombo, bool warn) { + list_t *mode_bindings = config->current_mode->gesture_bindings; + // overwrite the binding if it already exists + bool overwritten = false; + for (int i = 0; i < mode_bindings->length; ++i) { + struct sway_gesture_binding *config_binding = mode_bindings->items[i]; + if (binding_gesture_equal(binding, config_binding)) { + sway_log(SWAY_INFO, "Overwriting binding '%s' to `%s` from `%s`", + gesturecombo, binding->command, config_binding->command); + if (warn) { + config_add_swaynag_warning("Overwriting binding" + "'%s' to `%s` from `%s`", + gesturecombo, binding->command, + config_binding->command); + } + free_gesture_binding(config_binding); + mode_bindings->items[i] = binding; + overwritten = true; + } + } + + if (!overwritten) { + list_add(mode_bindings, binding); + sway_log(SWAY_DEBUG, "bindgesture - Bound %s to command `%s`", + gesturecombo, binding->command); + } + + return cmd_results_new(CMD_SUCCESS, NULL); +} + +/** + * Remove gesture binding from config + */ +static struct cmd_results *gesture_binding_remove( + struct sway_gesture_binding *binding, const char *gesturecombo) { + list_t *mode_bindings = config->current_mode->gesture_bindings; + for (int i = 0; i < mode_bindings->length; ++i) { + struct sway_gesture_binding *config_binding = mode_bindings->items[i]; + if (binding_gesture_equal(binding, config_binding)) { + free_gesture_binding(config_binding); + free_gesture_binding(binding); + list_del(mode_bindings, i); + sway_log(SWAY_DEBUG, "unbindgesture - Unbound %s gesture", + gesturecombo); + return cmd_results_new(CMD_SUCCESS, NULL); + } + } + + free_gesture_binding(binding); + return cmd_results_new(CMD_FAILURE, "Could not find gesture binding `%s`", + gesturecombo); +} + +/** + * Parse and execute bindgesture or unbindgesture command. + */ +static struct cmd_results *cmd_bind_or_unbind_gesture(int argc, char **argv, bool unbind) { + int minargs = 2; + char *bindtype = "bindgesture"; + if (unbind) { + minargs--; + bindtype = "unbindgesture"; + } + + struct cmd_results *error = NULL; + if ((error = checkarg(argc, bindtype, EXPECTED_AT_LEAST, minargs))) { + return error; + } + struct sway_gesture_binding *binding = calloc(1, sizeof(struct sway_gesture_binding)); + if (!binding) { + return cmd_results_new(CMD_FAILURE, "Unable to allocate binding"); + } + binding->input = strdup("*"); + + bool warn = true; + + // Handle flags + while (argc > 0) { + if (strcmp("--exact", argv[0]) == 0) { + binding->flags |= BINDING_EXACT; + } else if (strcmp("--no-warn", argv[0]) == 0) { + warn = false; + } else if (strncmp("--input-device=", argv[0], + strlen("--input-device=")) == 0) { + free(binding->input); + binding->input = strdup(argv[0] + strlen("--input-device=")); + } else { + break; + } + argv++; + argc--; + } + + if (argc < minargs) { + free(binding); + return cmd_results_new(CMD_FAILURE, + "Invalid %s command (expected at least %d " + "non-option arguments, got %d)", bindtype, minargs, argc); + } + + char* errmsg = NULL; + if ((errmsg = gesture_parse(argv[0], &binding->gesture))) { + free(binding); + struct cmd_results *final = cmd_results_new(CMD_FAILURE, + "Invalid %s command (%s)", + bindtype, errmsg); + free(errmsg); + return final; + } + + if (unbind) { + return gesture_binding_remove(binding, argv[0]); + } + binding->command = join_args(argv + 1, argc - 1); + return gesture_binding_add(binding, argv[0], warn); +} + +struct cmd_results *cmd_bindgesture(int argc, char **argv) { + return cmd_bind_or_unbind_gesture(argc, argv, false); +} + +struct cmd_results *cmd_unbindgesture(int argc, char **argv) { + return cmd_bind_or_unbind_gesture(argc, argv, true); +} diff --git a/sway/commands/input.c b/sway/commands/input.c index 77acb671..ea531659 100644 --- a/sway/commands/input.c +++ b/sway/commands/input.c @@ -14,6 +14,7 @@ static const struct cmd_handler input_handlers[] = { { "drag", input_cmd_drag }, { "drag_lock", input_cmd_drag_lock }, { "dwt", input_cmd_dwt }, + { "dwtp", input_cmd_dwtp }, { "events", input_cmd_events }, { "left_handed", input_cmd_left_handed }, { "map_from_region", input_cmd_map_from_region }, diff --git a/sway/commands/input/dwtp.c b/sway/commands/input/dwtp.c new file mode 100644 index 00000000..232e2b26 --- /dev/null +++ b/sway/commands/input/dwtp.c @@ -0,0 +1,25 @@ +#include <string.h> +#include <strings.h> +#include "sway/config.h" +#include "sway/commands.h" +#include "sway/input/input-manager.h" +#include "util.h" + +struct cmd_results *input_cmd_dwtp(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "dwtp", EXPECTED_AT_LEAST, 1))) { + return error; + } + struct input_config *ic = config->handler_context.input_config; + if (!ic) { + return cmd_results_new(CMD_FAILURE, "No input device defined."); + } + + if (parse_boolean(argv[0], true)) { + ic->dwtp = LIBINPUT_CONFIG_DWTP_ENABLED; + } else { + ic->dwtp = LIBINPUT_CONFIG_DWTP_DISABLED; + } + + return cmd_results_new(CMD_SUCCESS, NULL); +} diff --git a/sway/commands/input/xkb_switch_layout.c b/sway/commands/input/xkb_switch_layout.c index d6548a68..3cce4ec8 100644 --- a/sway/commands/input/xkb_switch_layout.c +++ b/sway/commands/input/xkb_switch_layout.c @@ -1,10 +1,16 @@ #define _POSIX_C_SOURCE 200809L #include <assert.h> +#include <wlr/interfaces/wlr_keyboard.h> #include "sway/config.h" #include "sway/commands.h" #include "sway/input/input-manager.h" #include "log.h" +struct xkb_switch_layout_action { + struct wlr_keyboard *keyboard; + xkb_layout_index_t layout; +}; + static void switch_layout(struct wlr_keyboard *kbd, xkb_layout_index_t idx) { xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); if (idx >= num_layouts) { @@ -28,10 +34,10 @@ static xkb_layout_index_t get_current_layout_index(struct wlr_keyboard *kbd) { return layout_idx; } -static void switch_layout_relative(struct wlr_keyboard *kbd, int dir) { +static xkb_layout_index_t get_layout_relative(struct wlr_keyboard *kbd, int dir) { xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); xkb_layout_index_t idx = get_current_layout_index(kbd); - switch_layout(kbd, (idx + num_layouts + dir) % num_layouts); + return (idx + num_layouts + dir) % num_layouts; } struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { @@ -66,6 +72,18 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { relative = 0; } + struct xkb_switch_layout_action *actions = calloc( + wl_list_length(&server.input->devices), + sizeof(struct xkb_switch_layout_action)); + size_t actions_len = 0; + + if (!actions) { + return cmd_results_new(CMD_FAILURE, "Unable to allocate actions"); + } + + /* Calculate new indexes first because switching a layout in one + keyboard may result in a change on other keyboards as well because + of keyboard groups. */ struct sway_input_device *dev; wl_list_for_each(dev, &server.input->devices, link) { if (strcmp(ic->identifier, "*") != 0 && @@ -76,12 +94,22 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { if (dev->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { continue; } + + struct xkb_switch_layout_action *action = + &actions[actions_len++]; + + action->keyboard = wlr_keyboard_from_input_device(dev->wlr_device); if (relative) { - switch_layout_relative(dev->wlr_device->keyboard, relative); + action->layout = get_layout_relative(action->keyboard, relative); } else { - switch_layout(dev->wlr_device->keyboard, layout); + action->layout = layout; } } + for (size_t i = 0; i < actions_len; i++) { + switch_layout(actions[i].keyboard, actions[i].layout); + } + free(actions); + return cmd_results_new(CMD_SUCCESS, NULL); } diff --git a/sway/commands/mode.c b/sway/commands/mode.c index e23e4ee4..7263efcb 100644 --- a/sway/commands/mode.c +++ b/sway/commands/mode.c @@ -11,10 +11,12 @@ // Must be in order for the bsearch static const struct cmd_handler mode_handlers[] = { { "bindcode", cmd_bindcode }, + { "bindgesture", cmd_bindgesture }, { "bindswitch", cmd_bindswitch }, { "bindsym", cmd_bindsym }, { "set", cmd_set }, { "unbindcode", cmd_unbindcode }, + { "unbindgesture", cmd_unbindgesture }, { "unbindswitch", cmd_unbindswitch }, { "unbindsym", cmd_unbindsym }, }; @@ -59,6 +61,7 @@ struct cmd_results *cmd_mode(int argc, char **argv) { mode->keycode_bindings = create_list(); mode->mouse_bindings = create_list(); mode->switch_bindings = create_list(); + mode->gesture_bindings = create_list(); mode->pango = pango; list_add(config->modes, mode); } diff --git a/sway/commands/move.c b/sway/commands/move.c index 1a05a7a6..7bd1fe3e 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c @@ -686,6 +686,9 @@ static struct cmd_results *cmd_move_workspace(int argc, char **argv) { arrange_output(old_output); arrange_output(new_output); + struct sway_seat *seat = config->handler_context.seat; + seat_consider_warp_to_focus(seat); + return cmd_results_new(CMD_SUCCESS, NULL); } @@ -788,15 +791,15 @@ static struct cmd_results *cmd_move_to_position_pointer( struct wlr_output *output = wlr_output_layout_output_at( root->output_layout, cursor->x, cursor->y); if (output) { - struct wlr_box *box = - wlr_output_layout_get_box(root->output_layout, output); - lx = fmax(lx, box->x); - ly = fmax(ly, box->y); - if (lx + container->pending.width > box->x + box->width) { - lx = box->x + box->width - container->pending.width; + struct wlr_box box; + wlr_output_layout_get_box(root->output_layout, output, &box); + lx = fmax(lx, box.x); + ly = fmax(ly, box.y); + if (lx + container->pending.width > box.x + box.width) { + lx = box.x + box.width - container->pending.width; } - if (ly + container->pending.height > box->y + box->height) { - ly = box->y + box->height - container->pending.height; + if (ly + container->pending.height > box.y + box.height) { + ly = box.y + box.height - container->pending.height; } } diff --git a/sway/commands/output.c b/sway/commands/output.c index 125df5a7..df32c673 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c @@ -18,6 +18,7 @@ static const struct cmd_handler output_handlers[] = { { "modeline", output_cmd_modeline }, { "pos", output_cmd_position }, { "position", output_cmd_position }, + { "power", output_cmd_power }, { "render_bit_depth", output_cmd_render_bit_depth }, { "res", output_cmd_mode }, { "resolution", output_cmd_mode }, @@ -26,6 +27,7 @@ static const struct cmd_handler output_handlers[] = { { "subpixel", output_cmd_subpixel }, { "toggle", output_cmd_toggle }, { "transform", output_cmd_transform }, + { "unplug", output_cmd_unplug }, }; struct cmd_results *cmd_output(int argc, char **argv) { diff --git a/sway/commands/output/background.c b/sway/commands/output/background.c index 68ee9fe1..67f212ff 100644 --- a/sway/commands/output/background.c +++ b/sway/commands/output/background.c @@ -102,19 +102,19 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { } char *conf_path = dirname(conf); - char *rel_path = src; - src = malloc(strlen(conf_path) + strlen(src) + 2); - if (!src) { - free(rel_path); + char *real_src = malloc(strlen(conf_path) + strlen(src) + 2); + if (!real_src) { + free(src); free(conf); sway_log(SWAY_ERROR, "Unable to allocate memory"); return cmd_results_new(CMD_FAILURE, "Unable to allocate resources"); } - sprintf(src, "%s/%s", conf_path, rel_path); - free(rel_path); + snprintf(real_src, strlen(conf_path) + strlen(src) + 2, "%s/%s", conf_path, src); + free(src); free(conf); + src = real_src; } bool can_access = access(src, F_OK) != -1; diff --git a/sway/commands/output/dpms.c b/sway/commands/output/dpms.c index 638c0ade..c7adbd58 100644 --- a/sway/commands/output/dpms.c +++ b/sway/commands/output/dpms.c @@ -1,45 +1,8 @@ +#include "log.h" #include "sway/commands.h" -#include "sway/config.h" -#include "sway/output.h" -#include "util.h" -#include <strings.h> struct cmd_results *output_cmd_dpms(int argc, char **argv) { - if (!config->handler_context.output_config) { - return cmd_results_new(CMD_FAILURE, "Missing output config"); - } - if (!argc) { - return cmd_results_new(CMD_INVALID, "Missing dpms argument."); - } - - enum config_dpms current_dpms = DPMS_ON; - - if (strcasecmp(argv[0], "toggle") == 0) { - - const char *oc_name = config->handler_context.output_config->name; - if (strcmp(oc_name, "*") == 0) { - return cmd_results_new(CMD_INVALID, - "Cannot apply toggle to all outputs."); - } - - struct sway_output *sway_output = all_output_by_name_or_id(oc_name); - if (!sway_output || !sway_output->wlr_output) { - return cmd_results_new(CMD_FAILURE, - "Cannot apply toggle to unknown output %s", oc_name); - } - - if (sway_output->enabled && !sway_output->wlr_output->enabled) { - current_dpms = DPMS_OFF; - } - } - - if (parse_boolean(argv[0], current_dpms == DPMS_ON)) { - config->handler_context.output_config->dpms_state = DPMS_ON; - } else { - config->handler_context.output_config->dpms_state = DPMS_OFF; - } - - config->handler_context.leftovers.argc = argc - 1; - config->handler_context.leftovers.argv = argv + 1; - return NULL; + sway_log(SWAY_INFO, "The \"output dpms\" command is deprecated, " + "use \"output power\" instead"); + return output_cmd_power(argc, argv); } diff --git a/sway/commands/output/power.c b/sway/commands/output/power.c new file mode 100644 index 00000000..e6ae2852 --- /dev/null +++ b/sway/commands/output/power.c @@ -0,0 +1,43 @@ +#include <strings.h> +#include "sway/commands.h" +#include "sway/config.h" +#include "sway/output.h" +#include "util.h" + +struct cmd_results *output_cmd_power(int argc, char **argv) { + if (!config->handler_context.output_config) { + return cmd_results_new(CMD_FAILURE, "Missing output config"); + } + if (argc == 0) { + return cmd_results_new(CMD_INVALID, "Missing power argument"); + } + + bool current = true; + if (strcasecmp(argv[0], "toggle") == 0) { + const char *oc_name = config->handler_context.output_config->name; + if (strcmp(oc_name, "*") == 0) { + return cmd_results_new(CMD_INVALID, + "Cannot apply toggle to all outputs"); + } + + struct sway_output *sway_output = all_output_by_name_or_id(oc_name); + if (!sway_output || !sway_output->wlr_output) { + return cmd_results_new(CMD_FAILURE, + "Cannot apply toggle to unknown output %s", oc_name); + } + + if (sway_output->enabled && !sway_output->wlr_output->enabled) { + current = false; + } + } + + if (parse_boolean(argv[0], current)) { + config->handler_context.output_config->power = 1; + } else { + config->handler_context.output_config->power = 0; + } + + config->handler_context.leftovers.argc = argc - 1; + config->handler_context.leftovers.argv = argv + 1; + return NULL; +} diff --git a/sway/commands/output/unplug.c b/sway/commands/output/unplug.c new file mode 100644 index 00000000..dfef626f --- /dev/null +++ b/sway/commands/output/unplug.c @@ -0,0 +1,54 @@ +#include <strings.h> +#include <wlr/config.h> +#include <wlr/backend/headless.h> +#include <wlr/backend/wayland.h> +#if WLR_HAS_X11_BACKEND +#include <wlr/backend/x11.h> +#endif +#include "sway/commands.h" +#include "sway/config.h" +#include "sway/output.h" + +static bool is_backend_allowed(struct wlr_backend *backend) { + if (wlr_backend_is_headless(backend)) { + return true; + } + if (wlr_backend_is_wl(backend)) { + return true; + } +#if WLR_HAS_X11_BACKEND + if (wlr_backend_is_x11(backend)) { + return true; + } +#endif + return false; +} + +/** + * This command is intended for developer use only. + */ +struct cmd_results *output_cmd_unplug(int argc, char **argv) { + if (!config->handler_context.output_config) { + return cmd_results_new(CMD_FAILURE, "Missing output config"); + } + + const char *oc_name = config->handler_context.output_config->name; + if (strcmp(oc_name, "*") == 0) { + return cmd_results_new(CMD_INVALID, "Won't unplug all outputs"); + } + + struct sway_output *sway_output = all_output_by_name_or_id(oc_name); + if (!sway_output) { + return cmd_results_new(CMD_INVALID, + "Cannot unplug unknown output %s", oc_name); + } + + if (!is_backend_allowed(sway_output->wlr_output->backend)) { + return cmd_results_new(CMD_INVALID, + "Can only unplug outputs with headless, wayland or x11 backend"); + } + + wlr_output_destroy(sway_output->wlr_output); + + return cmd_results_new(CMD_SUCCESS, NULL); +} diff --git a/sway/commands/rename.c b/sway/commands/rename.c index 3b855fdf..60a66d58 100644 --- a/sway/commands/rename.c +++ b/sway/commands/rename.c @@ -7,6 +7,7 @@ #include "sway/config.h" #include "sway/ipc-server.h" #include "sway/output.h" +#include "sway/desktop/launcher.h" #include "sway/tree/container.h" #include "sway/tree/workspace.h" #include "sway/tree/root.h" @@ -91,8 +92,6 @@ struct cmd_results *cmd_rename(int argc, char **argv) { sway_log(SWAY_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name); - root_rename_pid_workspaces(workspace->name, new_name); - free(workspace->name); workspace->name = new_name; diff --git a/sway/commands/seat/cursor.c b/sway/commands/seat/cursor.c index 749235eb..504a9f5e 100644 --- a/sway/commands/seat/cursor.c +++ b/sway/commands/seat/cursor.c @@ -111,8 +111,8 @@ static struct cmd_results *press_or_release(struct sway_cursor *cursor, : WLR_AXIS_ORIENTATION_HORIZONTAL; double delta = (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_LEFT) ? -1 : 1; - struct wlr_event_pointer_axis event = { - .device = NULL, + struct wlr_pointer_axis_event event = { + .pointer = NULL, .time_msec = 0, .source = WLR_AXIS_SOURCE_WHEEL, .orientation = orientation, |