diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-08-03 23:06:01 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-08-04 14:01:20 +1000 |
commit | 04489ff4209dc073027419d90961367cfb998fe8 (patch) | |
tree | d6f6213d2374e10a875e8ced872511e6e656ae3e /sway/tree/root.c | |
parent | Merge pull request #2419 from RedSoxFan/fix-2416 (diff) | |
download | sway-04489ff4209dc073027419d90961367cfb998fe8.tar.gz sway-04489ff4209dc073027419d90961367cfb998fe8.tar.zst sway-04489ff4209dc073027419d90961367cfb998fe8.zip |
Separate root-related code
This creates a root.c and moves bits and pieces from elsewhere into it.
* layout_init has been renamed to root_create and moved into root.c
* root_destroy has been created and is called on shutdown
* scratchpad code has been moved into root.c, because hidden scratchpad
containers are stored in the root struct
Diffstat (limited to 'sway/tree/root.c')
-rw-r--r-- | sway/tree/root.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/sway/tree/root.c b/sway/tree/root.c new file mode 100644 index 00000000..9f3965be --- /dev/null +++ b/sway/tree/root.c | |||
@@ -0,0 +1,147 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdbool.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <string.h> | ||
5 | #include <wlr/types/wlr_output_layout.h> | ||
6 | #include "sway/input/seat.h" | ||
7 | #include "sway/tree/arrange.h" | ||
8 | #include "sway/tree/container.h" | ||
9 | #include "sway/tree/root.h" | ||
10 | #include "sway/tree/workspace.h" | ||
11 | #include "list.h" | ||
12 | #include "log.h" | ||
13 | |||
14 | struct sway_container root_container; | ||
15 | |||
16 | static void output_layout_handle_change(struct wl_listener *listener, | ||
17 | void *data) { | ||
18 | arrange_windows(&root_container); | ||
19 | transaction_commit_dirty(); | ||
20 | } | ||
21 | |||
22 | void root_create(void) { | ||
23 | root_container.id = 0; // normally assigned in new_swayc() | ||
24 | root_container.type = C_ROOT; | ||
25 | root_container.layout = L_NONE; | ||
26 | root_container.name = strdup("root"); | ||
27 | root_container.instructions = create_list(); | ||
28 | root_container.children = create_list(); | ||
29 | root_container.current.children = create_list(); | ||
30 | wl_signal_init(&root_container.events.destroy); | ||
31 | |||
32 | root_container.sway_root = calloc(1, sizeof(*root_container.sway_root)); | ||
33 | root_container.sway_root->output_layout = wlr_output_layout_create(); | ||
34 | wl_list_init(&root_container.sway_root->outputs); | ||
35 | #ifdef HAVE_XWAYLAND | ||
36 | wl_list_init(&root_container.sway_root->xwayland_unmanaged); | ||
37 | #endif | ||
38 | wl_list_init(&root_container.sway_root->drag_icons); | ||
39 | wl_signal_init(&root_container.sway_root->events.new_container); | ||
40 | root_container.sway_root->scratchpad = create_list(); | ||
41 | |||
42 | root_container.sway_root->output_layout_change.notify = | ||
43 | output_layout_handle_change; | ||
44 | wl_signal_add(&root_container.sway_root->output_layout->events.change, | ||
45 | &root_container.sway_root->output_layout_change); | ||
46 | } | ||
47 | |||
48 | void root_destroy(void) { | ||
49 | // sway_root | ||
50 | wl_list_remove(&root_container.sway_root->output_layout_change.link); | ||
51 | list_free(root_container.sway_root->scratchpad); | ||
52 | wlr_output_layout_destroy(root_container.sway_root->output_layout); | ||
53 | free(root_container.sway_root); | ||
54 | |||
55 | // root_container | ||
56 | list_free(root_container.instructions); | ||
57 | list_free(root_container.children); | ||
58 | list_free(root_container.current.children); | ||
59 | free(root_container.name); | ||
60 | |||
61 | memset(&root_container, 0, sizeof(root_container)); | ||
62 | } | ||
63 | |||
64 | void root_scratchpad_add_container(struct sway_container *con) { | ||
65 | if (!sway_assert(!con->scratchpad, "Container is already in scratchpad")) { | ||
66 | return; | ||
67 | } | ||
68 | con->scratchpad = true; | ||
69 | list_add(root_container.sway_root->scratchpad, con); | ||
70 | |||
71 | struct sway_container *parent = con->parent; | ||
72 | container_set_floating(con, true); | ||
73 | container_remove_child(con); | ||
74 | arrange_windows(parent); | ||
75 | |||
76 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
77 | seat_set_focus(seat, seat_get_focus_inactive(seat, parent)); | ||
78 | } | ||
79 | |||
80 | void root_scratchpad_remove_container(struct sway_container *con) { | ||
81 | if (!sway_assert(con->scratchpad, "Container is not in scratchpad")) { | ||
82 | return; | ||
83 | } | ||
84 | con->scratchpad = false; | ||
85 | for (int i = 0; i < root_container.sway_root->scratchpad->length; ++i) { | ||
86 | if (root_container.sway_root->scratchpad->items[i] == con) { | ||
87 | list_del(root_container.sway_root->scratchpad, i); | ||
88 | break; | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | |||
93 | void root_scratchpad_show(struct sway_container *con) { | ||
94 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
95 | struct sway_container *ws = seat_get_focus(seat); | ||
96 | if (ws->type != C_WORKSPACE) { | ||
97 | ws = container_parent(ws, C_WORKSPACE); | ||
98 | } | ||
99 | |||
100 | // If the current con or any of its parents are in fullscreen mode, we | ||
101 | // first need to disable it before showing the scratchpad con. | ||
102 | if (ws->sway_workspace->fullscreen) { | ||
103 | container_set_fullscreen(ws->sway_workspace->fullscreen, false); | ||
104 | } | ||
105 | |||
106 | // Show the container | ||
107 | if (con->parent) { | ||
108 | container_remove_child(con); | ||
109 | } | ||
110 | container_add_child(ws->sway_workspace->floating, con); | ||
111 | |||
112 | // Make sure the container's center point overlaps this workspace | ||
113 | double center_lx = con->x + con->width / 2; | ||
114 | double center_ly = con->y + con->height / 2; | ||
115 | |||
116 | struct wlr_box workspace_box; | ||
117 | container_get_box(ws, &workspace_box); | ||
118 | if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) { | ||
119 | // Maybe resize it | ||
120 | if (con->width > ws->width || con->height > ws->height) { | ||
121 | container_init_floating(con); | ||
122 | } | ||
123 | |||
124 | // Center it | ||
125 | double new_lx = ws->x + (ws->width - con->width) / 2; | ||
126 | double new_ly = ws->y + (ws->height - con->height) / 2; | ||
127 | container_floating_move_to(con, new_lx, new_ly); | ||
128 | } | ||
129 | |||
130 | arrange_windows(ws); | ||
131 | seat_set_focus(seat, seat_get_focus_inactive(seat, con)); | ||
132 | |||
133 | container_set_dirty(con->parent); | ||
134 | } | ||
135 | |||
136 | void root_scratchpad_hide(struct sway_container *con) { | ||
137 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
138 | struct sway_container *focus = seat_get_focus(seat); | ||
139 | struct sway_container *ws = container_parent(con, C_WORKSPACE); | ||
140 | |||
141 | container_remove_child(con); | ||
142 | arrange_windows(ws); | ||
143 | if (con == focus) { | ||
144 | seat_set_focus(seat, seat_get_focus_inactive(seat, ws)); | ||
145 | } | ||
146 | list_move_to_end(root_container.sway_root->scratchpad, con); | ||
147 | } | ||