diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-07-16 15:39:08 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-16 15:39:08 -0700 |
commit | d6bd314dffb7385eec73de40f0fdd5775cd5941b (patch) | |
tree | 1cec389e971cda3e42766c07789d0f51c2d39715 /sway/tree | |
parent | 297e32126f1f8b27f51989b863e4ea1c9fce6a96 (diff) | |
parent | 255dc8bbb040c4f268f318bde86701227d82da3f (diff) | |
download | sway-d6bd314dffb7385eec73de40f0fdd5775cd5941b.tar.xz |
Merge pull request #2276 from RyanDwyer/urgency
Implement urgency base functionality
Diffstat (limited to 'sway/tree')
-rw-r--r-- | sway/tree/container.c | 34 | ||||
-rw-r--r-- | sway/tree/layout.c | 11 | ||||
-rw-r--r-- | sway/tree/view.c | 41 | ||||
-rw-r--r-- | sway/tree/workspace.c | 11 |
4 files changed, 87 insertions, 10 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c index 35f67cce..6d52c38c 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -674,16 +674,23 @@ struct sway_container *floating_container_at(double lx, double ly, void container_for_each_descendant_dfs(struct sway_container *container, void (*f)(struct sway_container *container, void *data), void *data) { - if (container) { - if (container->children) { - for (int i = 0; i < container->children->length; ++i) { - struct sway_container *child = - container->children->items[i]; - container_for_each_descendant_dfs(child, f, data); - } + if (!container) { + return; + } + if (container->children) { + for (int i = 0; i < container->children->length; ++i) { + struct sway_container *child = container->children->items[i]; + container_for_each_descendant_dfs(child, f, data); + } + } + if (container->type == C_WORKSPACE) { + struct sway_container *floating = container->sway_workspace->floating; + for (int i = 0; i < floating->children->length; ++i) { + struct sway_container *child = floating->children->items[i]; + container_for_each_descendant_dfs(child, f, data); } - f(container, data); } + f(container, data); } void container_for_each_descendant_bfs(struct sway_container *con, @@ -1063,6 +1070,8 @@ void container_floating_move_to(struct sway_container *con, container_add_child(new_workspace->sway_workspace->floating, con); arrange_windows(old_workspace); arrange_windows(new_workspace); + workspace_detect_urgent(old_workspace); + workspace_detect_urgent(new_workspace); } } @@ -1073,3 +1082,12 @@ void container_set_dirty(struct sway_container *container) { container->dirty = true; list_add(server.dirty_containers, container); } + +static bool find_urgent_iterator(struct sway_container *con, + void *data) { + return con->type == C_VIEW && view_is_urgent(con->sway_view); +} + +bool container_has_urgent_child(struct sway_container *container) { + return container_find(container, find_urgent_iterator, NULL); +} diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 54ddb3f9..197a2fc8 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -225,6 +225,15 @@ void container_move_to(struct sway_container *container, } } } + // Update workspace urgent state + struct sway_container *old_workspace = old_parent; + if (old_workspace->type != C_WORKSPACE) { + old_workspace = container_parent(old_workspace, C_WORKSPACE); + } + if (new_workspace != old_workspace) { + workspace_detect_urgent(new_workspace); + workspace_detect_urgent(old_workspace); + } } static bool sway_dir_to_wlr(enum movement_direction dir, @@ -548,6 +557,8 @@ void container_move(struct sway_container *container, } if (last_ws && next_ws && last_ws != next_ws) { ipc_event_workspace(last_ws, container, "focus"); + workspace_detect_urgent(last_ws); + workspace_detect_urgent(next_ws); } } diff --git a/sway/tree/view.c b/sway/tree/view.c index 10c97518..76e0f42c 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); } @@ -609,16 +610,26 @@ 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; + } + + struct sway_container *parent; + struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); + if (view->is_fullscreen) { - struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); ws->sway_workspace->fullscreen = NULL; - container_destroy(view->swayc); + parent = container_destroy(view->swayc); arrange_windows(ws->parent); } else { struct sway_container *parent = container_destroy(view->swayc); arrange_windows(parent); } + if (parent->type >= C_WORKSPACE) { // if the workspace still exists + workspace_detect_urgent(ws); + } transaction_commit_dirty(); view->surface = NULL; } @@ -1067,3 +1078,29 @@ 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); + + ipc_event_window(view->swayc, "urgent"); + + struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); + workspace_detect_urgent(ws); +} + +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..622f01ec 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,13 @@ struct sway_container *workspace_output_get_highest_available( return NULL; } + +void workspace_detect_urgent(struct sway_container *workspace) { + bool new_urgent = container_has_urgent_child(workspace); + + if (workspace->sway_workspace->urgent != new_urgent) { + workspace->sway_workspace->urgent = new_urgent; + ipc_event_workspace(NULL, workspace, "urgent"); + container_damage_whole(workspace); + } +} |