From ba3511b2431d331b735770e38e6bbd83cb5a9d66 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 9 Jul 2018 22:39:47 +0100 Subject: Remove `clipboard` command and `get_clipboard` message --- include/sway/commands.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/sway/commands.h') diff --git a/include/sway/commands.h b/include/sway/commands.h index 6d17144a..dda0606a 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -95,7 +95,6 @@ sway_cmd cmd_client_unfocused; sway_cmd cmd_client_urgent; sway_cmd cmd_client_placeholder; sway_cmd cmd_client_background; -sway_cmd cmd_clipboard; sway_cmd cmd_commands; sway_cmd cmd_debuglog; sway_cmd cmd_default_border; -- cgit v1.2.3 From 41b80c28dfafb9bc13b68e4d5d2811d311b59863 Mon Sep 17 00:00:00 2001 From: Robert Kubosz Date: Wed, 11 Jul 2018 22:03:06 +0200 Subject: add scroll button option This commit introduces a scroll_button option, which is intended to be used with scroll_method. Now user can edit his sway config and add an scroll_button option to device section. --- include/sway/commands.h | 1 + include/sway/config.h | 1 + sway/commands/input.c | 1 + sway/commands/input/scroll_button.c | 31 +++++++++++++++++++++++++++++++ sway/config/input.c | 4 ++++ sway/input/input-manager.c | 6 ++++++ sway/meson.build | 1 + 7 files changed, 45 insertions(+) create mode 100644 sway/commands/input/scroll_button.c (limited to 'include/sway/commands.h') diff --git a/include/sway/commands.h b/include/sway/commands.h index dda0606a..32d6cefd 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -207,6 +207,7 @@ sway_cmd input_cmd_natural_scroll; sway_cmd input_cmd_pointer_accel; sway_cmd input_cmd_repeat_delay; sway_cmd input_cmd_repeat_rate; +sway_cmd input_cmd_scroll_button; sway_cmd input_cmd_scroll_method; sway_cmd input_cmd_tap; sway_cmd input_cmd_xkb_layout; diff --git a/include/sway/config.h b/include/sway/config.h index 99575274..75acd4f2 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -75,6 +75,7 @@ struct input_config { float pointer_accel; int repeat_delay; int repeat_rate; + int scroll_button; int scroll_method; int send_events; int tap; diff --git a/sway/commands/input.c b/sway/commands/input.c index 574e1f8c..e7906b0e 100644 --- a/sway/commands/input.c +++ b/sway/commands/input.c @@ -20,6 +20,7 @@ static struct cmd_handler input_handlers[] = { { "pointer_accel", input_cmd_pointer_accel }, { "repeat_delay", input_cmd_repeat_delay }, { "repeat_rate", input_cmd_repeat_rate }, + { "scroll_button", input_cmd_scroll_button }, { "scroll_method", input_cmd_scroll_method }, { "tap", input_cmd_tap }, { "xkb_layout", input_cmd_xkb_layout }, diff --git a/sway/commands/input/scroll_button.c b/sway/commands/input/scroll_button.c new file mode 100644 index 00000000..a9d697cf --- /dev/null +++ b/sway/commands/input/scroll_button.c @@ -0,0 +1,31 @@ +#include +#include +#include "sway/config.h" +#include "sway/commands.h" +#include "sway/input/input-manager.h" + +struct cmd_results *input_cmd_scroll_button(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "scroll_button", EXPECTED_AT_LEAST, 1))) { + return error; + } + struct input_config *current_input_config = + config->handler_context.input_config; + if (!current_input_config) { + return cmd_results_new(CMD_FAILURE, "scroll_button", + "No input device defined."); + } + struct input_config *new_config = + new_input_config(current_input_config->identifier); + + int scroll_button = atoi(argv[0]); + if (scroll_button < 1 || scroll_button > 10) { + free_input_config(new_config); + return cmd_results_new(CMD_INVALID, "scroll_button", + "Input out of range [1, 10]"); + } + new_config->scroll_button = scroll_button; + + apply_input_config(new_config); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} diff --git a/sway/config/input.c b/sway/config/input.c index 9840df18..62d77cf7 100644 --- a/sway/config/input.c +++ b/sway/config/input.c @@ -28,6 +28,7 @@ struct input_config *new_input_config(const char* identifier) { input->accel_profile = INT_MIN; input->pointer_accel = FLT_MIN; input->scroll_method = INT_MIN; + input->scroll_button = INT_MIN; input->left_handed = INT_MIN; input->repeat_delay = INT_MIN; input->repeat_rate = INT_MIN; @@ -70,6 +71,9 @@ void merge_input_config(struct input_config *dst, struct input_config *src) { if (src->scroll_method != INT_MIN) { dst->scroll_method = src->scroll_method; } + if (src->scroll_button != INT_MIN) { + dst->scroll_button= src->scroll_button; + } if (src->send_events != INT_MIN) { dst->send_events = src->send_events; } diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index daaf1fb6..b18989d0 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c @@ -158,6 +158,12 @@ static void input_manager_libinput_config_pointer( libinput_device_config_accel_set_speed(libinput_device, ic->pointer_accel); } + if (ic->scroll_button != INT_MIN) { + wlr_log(WLR_DEBUG, "libinput_config_pointer(%s) scroll_set_button(%d)", + ic->identifier, ic->scroll_button); + libinput_device_config_scroll_set_button(libinput_device, + ic->scroll_button); + } if (ic->scroll_method != INT_MIN) { wlr_log(WLR_DEBUG, "libinput_config_pointer(%s) scroll_set_method(%d)", ic->identifier, ic->scroll_method); diff --git a/sway/meson.build b/sway/meson.build index 72192917..6fc78db3 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -118,6 +118,7 @@ sway_sources = files( 'commands/input/pointer_accel.c', 'commands/input/repeat_delay.c', 'commands/input/repeat_rate.c', + 'commands/input/scroll_button.c', 'commands/input/scroll_method.c', 'commands/input/tap.c', 'commands/input/xkb_layout.c', -- cgit v1.2.3 From 13c6627ddb7dbe235426e123ee6ff8e6794bda6d Mon Sep 17 00:00:00 2001 From: Brian Ashworth Date: Sat, 14 Jul 2018 01:01:47 -0400 Subject: Implement tap_button_map for input devices --- include/sway/commands.h | 1 + include/sway/config.h | 1 + sway/commands/input.c | 1 + sway/commands/input/tap_button_map.c | 33 +++++++++++++++++++++++++++++++++ sway/config/input.c | 4 ++++ sway/input/input-manager.c | 6 ++++++ sway/meson.build | 1 + sway/sway-input.5.scd | 6 ++++++ 8 files changed, 53 insertions(+) create mode 100644 sway/commands/input/tap_button_map.c (limited to 'include/sway/commands.h') diff --git a/include/sway/commands.h b/include/sway/commands.h index 32d6cefd..3ebd0002 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -210,6 +210,7 @@ sway_cmd input_cmd_repeat_rate; sway_cmd input_cmd_scroll_button; sway_cmd input_cmd_scroll_method; sway_cmd input_cmd_tap; +sway_cmd input_cmd_tap_button_map; sway_cmd input_cmd_xkb_layout; sway_cmd input_cmd_xkb_model; sway_cmd input_cmd_xkb_options; diff --git a/include/sway/config.h b/include/sway/config.h index 75acd4f2..f660a269 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -79,6 +79,7 @@ struct input_config { int scroll_method; int send_events; int tap; + int tap_button_map; char *xkb_layout; char *xkb_model; diff --git a/sway/commands/input.c b/sway/commands/input.c index e7906b0e..5b203ea0 100644 --- a/sway/commands/input.c +++ b/sway/commands/input.c @@ -23,6 +23,7 @@ static struct cmd_handler input_handlers[] = { { "scroll_button", input_cmd_scroll_button }, { "scroll_method", input_cmd_scroll_method }, { "tap", input_cmd_tap }, + { "tap_button_map", input_cmd_tap_button_map }, { "xkb_layout", input_cmd_xkb_layout }, { "xkb_model", input_cmd_xkb_model }, { "xkb_options", input_cmd_xkb_options }, diff --git a/sway/commands/input/tap_button_map.c b/sway/commands/input/tap_button_map.c new file mode 100644 index 00000000..bdbba472 --- /dev/null +++ b/sway/commands/input/tap_button_map.c @@ -0,0 +1,33 @@ +#include +#include +#include "sway/config.h" +#include "sway/commands.h" +#include "sway/input/input-manager.h" + +struct cmd_results *input_cmd_tap_button_map(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "tap_button_map", EXPECTED_AT_LEAST, 1))) { + return error; + } + struct input_config *current_input_config = + config->handler_context.input_config; + if (!current_input_config) { + return cmd_results_new(CMD_FAILURE, "tap_button_map", + "No input device defined."); + } + struct input_config *new_config = + new_input_config(current_input_config->identifier); + + if (strcasecmp(argv[0], "lrm") == 0) { + new_config->tap_button_map = LIBINPUT_CONFIG_TAP_MAP_LRM; + } else if (strcasecmp(argv[0], "lmr") == 0) { + new_config->tap_button_map = LIBINPUT_CONFIG_TAP_MAP_LMR; + } else { + free_input_config(new_config); + return cmd_results_new(CMD_INVALID, "tap_button_map", + "Expected 'tap_button_map '"); + } + + apply_input_config(new_config); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} diff --git a/sway/config/input.c b/sway/config/input.c index cbd7d5f0..8d687a6d 100644 --- a/sway/config/input.c +++ b/sway/config/input.c @@ -19,6 +19,7 @@ struct input_config *new_input_config(const char* identifier) { } input->tap = INT_MIN; + input->tap_button_map = INT_MIN; input->drag_lock = INT_MIN; input->dwt = INT_MIN; input->send_events = INT_MIN; @@ -80,6 +81,9 @@ void merge_input_config(struct input_config *dst, struct input_config *src) { if (src->tap != INT_MIN) { dst->tap = src->tap; } + if (src->tap_button_map != INT_MIN) { + dst->tap_button_map = src->tap_button_map; + } if (src->xkb_layout) { free(dst->xkb_layout); dst->xkb_layout = strdup(src->xkb_layout); diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index b18989d0..0b7cb766 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c @@ -181,6 +181,12 @@ static void input_manager_libinput_config_pointer( ic->identifier, ic->tap); libinput_device_config_tap_set_enabled(libinput_device, ic->tap); } + if (ic->tap_button_map != INT_MIN) { + wlr_log(WLR_DEBUG, "libinput_config_pointer(%s) tap_set_button_map(%d)", + ic->identifier, ic->tap); + libinput_device_config_tap_set_button_map(libinput_device, + ic->tap_button_map); + } } static void handle_device_destroy(struct wl_listener *listener, void *data) { diff --git a/sway/meson.build b/sway/meson.build index 6fc78db3..f878450d 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -121,6 +121,7 @@ sway_sources = files( 'commands/input/scroll_button.c', 'commands/input/scroll_method.c', 'commands/input/tap.c', + 'commands/input/tap_button_map.c', 'commands/input/xkb_layout.c', 'commands/input/xkb_model.c', 'commands/input/xkb_options.c', diff --git a/sway/sway-input.5.scd b/sway/sway-input.5.scd index 4bc66394..b6391431 100644 --- a/sway/sway-input.5.scd +++ b/sway/sway-input.5.scd @@ -100,6 +100,12 @@ For more information on these xkb configuration options, see *input* tap enabled|disabled Enables or disables tap for specified input device. +*input* tap_button_map lrm|lmr + Specifies which button mapping to use for tapping. _lrm_ treats 1 finger as + left click, 2 fingers as right click, and 3 fingers as middle click. _lmr_ + treats 1 finger as left click, 2 fingers as middle click, and 3 fingers as + right click. + ## SEAT CONFIGURATION Configure options for multiseat mode. sway-seat commands must be used inside a -- cgit v1.2.3 From 315d5311b2004b9e148e7b52a7de161b6dfe3878 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 15 Jul 2018 22:43:33 +1000 Subject: Implement urgency base functionality Introduces a command to manually set urgency, as well as rendering of urgent views, sending the IPC event, removing urgency after focused for one second, and matching urgent views via criteria. --- include/sway/commands.h | 1 + include/sway/tree/view.h | 8 ++++++++ include/sway/tree/workspace.h | 3 +++ sway/commands.c | 1 + sway/commands/urgent.c | 36 +++++++++++++++++++++++++++++++++++ sway/criteria.c | 44 +++++++++++++++++++++++++++++++++++++++++-- sway/desktop/render.c | 24 +++++++++++++++++++---- sway/input/seat.c | 16 ++++++++++++++++ sway/ipc-json.c | 3 ++- sway/meson.build | 1 + sway/tree/view.c | 30 +++++++++++++++++++++++++++++ sway/tree/workspace.c | 10 ++++++++++ 12 files changed, 170 insertions(+), 7 deletions(-) create mode 100644 sway/commands/urgent.c (limited to 'include/sway/commands.h') diff --git a/include/sway/commands.h b/include/sway/commands.h index 3ebd0002..1e93e2a3 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -152,6 +152,7 @@ sway_cmd cmd_swaybg_command; sway_cmd cmd_swap; sway_cmd cmd_title_format; sway_cmd cmd_unmark; +sway_cmd cmd_urgent; sway_cmd cmd_workspace; sway_cmd cmd_ws_auto_back_and_forth; sway_cmd cmd_workspace_layout; diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 21d6403e..9022f7a6 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -70,6 +70,10 @@ struct sway_view { bool border_left; bool border_right; + struct timespec urgent; + bool allow_request_urgent; + struct wl_event_source *urgent_timer; + bool destroying; list_t *executed_criteria; // struct criteria * @@ -305,4 +309,8 @@ void view_update_marks_textures(struct sway_view *view); */ bool view_is_visible(struct sway_view *view); +void view_set_urgent(struct sway_view *view, bool enable); + +bool view_is_urgent(struct sway_view *view); + #endif diff --git a/include/sway/tree/workspace.h b/include/sway/tree/workspace.h index c72a4ac0..8c2f4cd5 100644 --- a/include/sway/tree/workspace.h +++ b/include/sway/tree/workspace.h @@ -42,4 +42,7 @@ void workspace_output_add_priority(struct sway_container *workspace, struct sway_container *workspace_output_get_highest_available( struct sway_container *ws, struct sway_container *exclude); + +bool workspace_is_urgent(struct sway_container *workspace); + #endif diff --git a/sway/commands.c b/sway/commands.c index addd64a6..3578e748 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -153,6 +153,7 @@ static struct cmd_handler command_handlers[] = { { "swap", cmd_swap }, { "title_format", cmd_title_format }, { "unmark", cmd_unmark }, + { "urgent", cmd_urgent }, }; static int handler_compare(const void *_a, const void *_b) { diff --git a/sway/commands/urgent.c b/sway/commands/urgent.c new file mode 100644 index 00000000..d199858a --- /dev/null +++ b/sway/commands/urgent.c @@ -0,0 +1,36 @@ +#include "log.h" +#include "sway/commands.h" +#include "sway/config.h" +#include "sway/tree/arrange.h" +#include "sway/tree/container.h" +#include "sway/tree/view.h" +#include "sway/tree/layout.h" + +struct cmd_results *cmd_urgent(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "urgent", EXPECTED_EQUAL_TO, 1))) { + return error; + } + struct sway_container *container = + config->handler_context.current_container; + if (container->type != C_VIEW) { + return cmd_results_new(CMD_INVALID, "urgent", + "Only views can be urgent"); + } + struct sway_view *view = container->sway_view; + + if (strcmp(argv[0], "enable") == 0) { + view_set_urgent(view, true); + } else if (strcmp(argv[0], "disable") == 0) { + view_set_urgent(view, false); + } else if (strcmp(argv[0], "allow") == 0) { + view->allow_request_urgent = true; + } else if (strcmp(argv[0], "deny") == 0) { + view->allow_request_urgent = false; + } else { + return cmd_results_new(CMD_INVALID, "urgent", + "Expected 'urgent '"); + } + + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} diff --git a/sway/criteria.c b/sway/criteria.c index 29a3668b..c999d248 100644 --- a/sway/criteria.c +++ b/sway/criteria.c @@ -46,6 +46,31 @@ static int regex_cmp(const char *item, const pcre *regex) { return pcre_exec(regex, NULL, item, strlen(item), 0, 0, NULL, 0); } +static int cmp_urgent(const void *_a, const void *_b) { + struct sway_view *a = *(void **)_a; + struct sway_view *b = *(void **)_b; + + if (a->urgent.tv_sec < b->urgent.tv_sec) { + return -1; + } else if (a->urgent.tv_sec > b->urgent.tv_sec) { + return 1; + } + if (a->urgent.tv_nsec < b->urgent.tv_nsec) { + return -1; + } else if (a->urgent.tv_nsec > b->urgent.tv_nsec) { + return 1; + } + return 0; +} + +static void find_urgent_iterator(struct sway_container *swayc, void *data) { + if (swayc->type != C_VIEW || !view_is_urgent(swayc->sway_view)) { + return; + } + list_t *urgent_views = data; + list_add(urgent_views, swayc->sway_view); +} + static bool criteria_matches_view(struct criteria *criteria, struct sway_view *view) { if (criteria->title) { @@ -133,8 +158,23 @@ static bool criteria_matches_view(struct criteria *criteria, } if (criteria->urgent) { - // TODO - return false; + if (!view_is_urgent(view)) { + return false; + } + list_t *urgent_views = create_list(); + container_for_each_descendant_dfs(&root_container, + find_urgent_iterator, urgent_views); + list_stable_sort(urgent_views, cmp_urgent); + struct sway_view *target; + if (criteria->urgent == 'o') { // oldest + target = urgent_views->items[0]; + } else { // latest + target = urgent_views->items[urgent_views->length - 1]; + } + list_free(urgent_views); + if (view != target) { + return false; + } } if (criteria->workspace) { diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 17fe823a..3180f8ba 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -553,7 +553,11 @@ static void render_container_simple(struct sway_output *output, struct wlr_texture *marks_texture; struct sway_container_state *state = &child->current; - if (state->focused || parent_focused) { + if (view_is_urgent(view)) { + colors = &config->border_colors.urgent; + title_texture = child->title_urgent; + marks_texture = view->marks_urgent; + } else if (state->focused || parent_focused) { colors = &config->border_colors.focused; title_texture = child->title_focused; marks_texture = view->marks_focused; @@ -608,7 +612,11 @@ static void render_container_tabbed(struct sway_output *output, struct wlr_texture *title_texture; struct wlr_texture *marks_texture; - if (cstate->focused || parent_focused) { + if (view && view_is_urgent(view)) { + colors = &config->border_colors.urgent; + title_texture = child->title_urgent; + marks_texture = view->marks_urgent; + } else if (cstate->focused || parent_focused) { colors = &config->border_colors.focused; title_texture = child->title_focused; marks_texture = view ? view->marks_focused : NULL; @@ -671,7 +679,11 @@ static void render_container_stacked(struct sway_output *output, struct wlr_texture *title_texture; struct wlr_texture *marks_texture; - if (cstate->focused || parent_focused) { + if (view && view_is_urgent(view)) { + colors = &config->border_colors.urgent; + title_texture = child->title_urgent; + marks_texture = view->marks_urgent; + } else if (cstate->focused || parent_focused) { colors = &config->border_colors.focused; title_texture = child->title_focused; marks_texture = view ? view->marks_focused : NULL; @@ -731,7 +743,11 @@ static void render_floating_container(struct sway_output *soutput, struct wlr_texture *title_texture; struct wlr_texture *marks_texture; - if (con->current.focused) { + if (view_is_urgent(view)) { + colors = &config->border_colors.urgent; + title_texture = con->title_urgent; + marks_texture = view->marks_urgent; + } else if (con->current.focused) { colors = &config->border_colors.focused; title_texture = con->title_focused; marks_texture = view->marks_focused; diff --git a/sway/input/seat.c b/sway/input/seat.c index 74f1375e..7058cc92 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -594,6 +594,12 @@ static void seat_send_unfocus(struct sway_container *container, } } +static int handle_urgent_timeout(void *data) { + struct sway_view *view = data; + view_set_urgent(view, false); + return 0; +} + void seat_set_focus_warp(struct sway_seat *seat, struct sway_container *container, bool warp) { if (seat->focused_layer) { @@ -670,6 +676,16 @@ void seat_set_focus_warp(struct sway_seat *seat, } } + // If urgent, start a timer to unset it + if (container && container->type == C_VIEW && + view_is_urgent(container->sway_view) && + !container->sway_view->urgent_timer) { + struct sway_view *view = container->sway_view; + view->urgent_timer = wl_event_loop_add_timer(server.wl_event_loop, + handle_urgent_timeout, view); + wl_event_source_timer_update(view->urgent_timer, 1000); + } + // If we've focused a floating container, bring it to the front. // We do this by putting it at the end of the floating list. // This must happen for both the pending and current children lists. diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 3d0e88f0..8c48e724 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -170,7 +170,8 @@ static void ipc_json_describe_workspace(struct sway_container *workspace, json_object_object_add(object, "output", workspace->parent ? json_object_new_string(workspace->parent->name) : NULL); json_object_object_add(object, "type", json_object_new_string("workspace")); - json_object_object_add(object, "urgent", json_object_new_boolean(false)); + json_object_object_add(object, "urgent", + json_object_new_boolean(workspace_is_urgent(workspace))); json_object_object_add(object, "representation", workspace->formatted_title ? json_object_new_string(workspace->formatted_title) : NULL); diff --git a/sway/meson.build b/sway/meson.build index f878450d..b64bd137 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -76,6 +76,7 @@ sway_sources = files( 'commands/swap.c', 'commands/title_format.c', 'commands/unmark.c', + 'commands/urgent.c', 'commands/workspace.c', 'commands/workspace_layout.c', 'commands/ws_auto_back_and_forth.c', diff --git a/sway/tree/view.c b/sway/tree/view.c index bf380d98..a2dbe92c 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -25,6 +25,7 @@ void view_init(struct sway_view *view, enum sway_view_type type, view->impl = impl; view->executed_criteria = create_list(); view->marks = create_list(); + view->allow_request_urgent = true; wl_signal_init(&view->events.unmap); } @@ -589,6 +590,11 @@ void view_unmap(struct sway_view *view) { wl_list_remove(&view->surface_new_subsurface.link); wl_list_remove(&view->container_reparent.link); + if (view->urgent_timer) { + wl_event_source_remove(view->urgent_timer); + view->urgent_timer = NULL; + } + if (view->is_fullscreen) { struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); ws->sway_workspace->fullscreen = NULL; @@ -1047,3 +1053,27 @@ bool view_is_visible(struct sway_view *view) { } return true; } + +void view_set_urgent(struct sway_view *view, bool enable) { + if (enable) { + struct sway_seat *seat = input_manager_current_seat(input_manager); + if (seat_get_focus(seat) == view->swayc) { + return; + } + clock_gettime(CLOCK_MONOTONIC, &view->urgent); + } else { + view->urgent = (struct timespec){ 0 }; + if (view->urgent_timer) { + wl_event_source_remove(view->urgent_timer); + view->urgent_timer = NULL; + } + } + container_damage_whole(view->swayc); + + struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); + ipc_event_workspace(ws, NULL, "urgent"); +} + +bool view_is_urgent(struct sway_view *view) { + return view->urgent.tv_sec || view->urgent.tv_nsec; +} diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 2a2d834a..d71b0a53 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -11,6 +11,7 @@ #include "sway/ipc-server.h" #include "sway/tree/arrange.h" #include "sway/tree/container.h" +#include "sway/tree/view.h" #include "sway/tree/workspace.h" #include "list.h" #include "log.h" @@ -518,3 +519,12 @@ struct sway_container *workspace_output_get_highest_available( return NULL; } + +static bool find_urgent_iterator(struct sway_container *con, + void *data) { + return con->type == C_VIEW && view_is_urgent(con->sway_view); +} + +bool workspace_is_urgent(struct sway_container *workspace) { + return container_find(workspace, find_urgent_iterator, NULL); +} -- cgit v1.2.3