aboutsummaryrefslogtreecommitdiff
path: root/sway/tree
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2018-07-16 15:39:08 -0700
committerGitHub <noreply@github.com>2018-07-16 15:39:08 -0700
commitd6bd314dffb7385eec73de40f0fdd5775cd5941b (patch)
tree1cec389e971cda3e42766c07789d0f51c2d39715 /sway/tree
parent297e32126f1f8b27f51989b863e4ea1c9fce6a96 (diff)
parent255dc8bbb040c4f268f318bde86701227d82da3f (diff)
downloadsway-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.c34
-rw-r--r--sway/tree/layout.c11
-rw-r--r--sway/tree/view.c41
-rw-r--r--sway/tree/workspace.c11
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);
+ }
+}