aboutsummaryrefslogtreecommitdiffstats
path: root/sway
diff options
context:
space:
mode:
authorLibravatar Tony Crisci <tony@dubstepdish.com>2018-04-04 00:20:44 -0400
committerLibravatar Tony Crisci <tony@dubstepdish.com>2018-04-04 00:20:44 -0400
commit741e3959e30283f5f699f7e9fa6620e3578b9c76 (patch)
tree8489f010c2f3e112722e7b999bacef18dfe418ef /sway
parentsimplify container close (diff)
parentMerge pull request #1722 from swaywm/swaybar-hidpi (diff)
downloadsway-741e3959e30283f5f699f7e9fa6620e3578b9c76.tar.gz
sway-741e3959e30283f5f699f7e9fa6620e3578b9c76.tar.zst
sway-741e3959e30283f5f699f7e9fa6620e3578b9c76.zip
Merge branch 'wlroots' into split-containers2
Diffstat (limited to 'sway')
-rw-r--r--sway/config/output.c11
-rw-r--r--sway/desktop/layer_shell.c29
-rw-r--r--sway/desktop/output.c40
-rw-r--r--sway/input/cursor.c11
-rw-r--r--sway/input/seat.c36
-rw-r--r--sway/tree/layout.c16
-rw-r--r--sway/tree/workspace.c18
7 files changed, 124 insertions, 37 deletions
diff --git a/sway/config/output.c b/sway/config/output.c
index c4b74ce2..1c298d37 100644
--- a/sway/config/output.c
+++ b/sway/config/output.c
@@ -123,11 +123,14 @@ void terminate_swaybg(pid_t pid) {
123void apply_output_config(struct output_config *oc, struct sway_container *output) { 123void apply_output_config(struct output_config *oc, struct sway_container *output) {
124 assert(output->type == C_OUTPUT); 124 assert(output->type == C_OUTPUT);
125 125
126 struct wlr_output_layout *output_layout =
127 root_container.sway_root->output_layout;
126 struct wlr_output *wlr_output = output->sway_output->wlr_output; 128 struct wlr_output *wlr_output = output->sway_output->wlr_output;
129
127 if (oc && oc->enabled == 0) { 130 if (oc && oc->enabled == 0) {
131 container_destroy(output);
128 wlr_output_layout_remove(root_container.sway_root->output_layout, 132 wlr_output_layout_remove(root_container.sway_root->output_layout,
129 wlr_output); 133 wlr_output);
130 container_destroy(output);
131 return; 134 return;
132 } 135 }
133 136
@@ -148,11 +151,9 @@ void apply_output_config(struct output_config *oc, struct sway_container *output
148 // Find position for it 151 // Find position for it
149 if (oc && (oc->x != -1 || oc->y != -1)) { 152 if (oc && (oc->x != -1 || oc->y != -1)) {
150 wlr_log(L_DEBUG, "Set %s position to %d, %d", oc->name, oc->x, oc->y); 153 wlr_log(L_DEBUG, "Set %s position to %d, %d", oc->name, oc->x, oc->y);
151 wlr_output_layout_add(root_container.sway_root->output_layout, 154 wlr_output_layout_add(output_layout, wlr_output, oc->x, oc->y);
152 wlr_output, oc->x, oc->y);
153 } else { 155 } else {
154 wlr_output_layout_add_auto(root_container.sway_root->output_layout, 156 wlr_output_layout_add_auto(output_layout, wlr_output);
155 wlr_output);
156 } 157 }
157 158
158 if (!oc || !oc->background) { 159 if (!oc || !oc->background) {
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c
index c18f51c7..663ec7ba 100644
--- a/sway/desktop/layer_shell.c
+++ b/sway/desktop/layer_shell.c
@@ -7,6 +7,8 @@
7#include <wlr/types/wlr_output_damage.h> 7#include <wlr/types/wlr_output_damage.h>
8#include <wlr/types/wlr_output.h> 8#include <wlr/types/wlr_output.h>
9#include <wlr/util/log.h> 9#include <wlr/util/log.h>
10#include "sway/input/input-manager.h"
11#include "sway/input/seat.h"
10#include "sway/layers.h" 12#include "sway/layers.h"
11#include "sway/output.h" 13#include "sway/output.h"
12#include "sway/server.h" 14#include "sway/server.h"
@@ -187,6 +189,31 @@ void arrange_layers(struct sway_output *output) {
187 &usable_area, false); 189 &usable_area, false);
188 arrange_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], 190 arrange_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
189 &usable_area, false); 191 &usable_area, false);
192
193 // Find topmost keyboard interactive layer, if such a layer exists
194 uint32_t layers_above_shell[] = {
195 ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
196 ZWLR_LAYER_SHELL_V1_LAYER_TOP,
197 };
198 size_t nlayers = sizeof(layers_above_shell) / sizeof(layers_above_shell[0]);
199 struct sway_layer_surface *layer, *topmost = NULL;
200 for (size_t i = 0; i < nlayers; ++i) {
201 wl_list_for_each_reverse(layer,
202 &output->layers[layers_above_shell[i]], link) {
203 if (layer->layer_surface->current.keyboard_interactive) {
204 topmost = layer;
205 break;
206 }
207 }
208 if (topmost != NULL) {
209 break;
210 }
211 }
212
213 struct sway_seat *seat;
214 wl_list_for_each(seat, &input_manager->seats, link) {
215 seat_set_focus_layer(seat, topmost ? topmost->layer_surface : NULL);
216 }
190} 217}
191 218
192static void handle_output_destroy(struct wl_listener *listener, void *data) { 219static void handle_output_destroy(struct wl_listener *listener, void *data) {
@@ -251,6 +278,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
251 sway_layer, map); 278 sway_layer, map);
252 struct sway_output *output = sway_layer->layer_surface->output->data; 279 struct sway_output *output = sway_layer->layer_surface->output->data;
253 wlr_output_damage_add_box(output->damage, &sway_layer->geo); 280 wlr_output_damage_add_box(output->damage, &sway_layer->geo);
281 wlr_surface_send_enter(sway_layer->layer_surface->surface,
282 sway_layer->layer_surface->output);
254} 283}
255 284
256static void handle_unmap(struct wl_listener *listener, void *data) { 285static void handle_unmap(struct wl_listener *listener, void *data) {
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 96f23291..8a4fb4a2 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -57,10 +57,7 @@ static void rotate_child_position(double *sx, double *sy, double sw, double sh,
57 */ 57 */
58static bool surface_intersect_output(struct wlr_surface *surface, 58static bool surface_intersect_output(struct wlr_surface *surface,
59 struct wlr_output_layout *output_layout, struct wlr_output *wlr_output, 59 struct wlr_output_layout *output_layout, struct wlr_output *wlr_output,
60 double lx, double ly, float rotation, struct wlr_box *box) { 60 double ox, double oy, float rotation, struct wlr_box *box) {
61 double ox = lx, oy = ly;
62 wlr_output_layout_output_coords(output_layout, wlr_output, &ox, &oy);
63
64 if (box != NULL) { 61 if (box != NULL) {
65 box->x = ox * wlr_output->scale; 62 box->x = ox * wlr_output->scale;
66 box->y = oy * wlr_output->scale; 63 box->y = oy * wlr_output->scale;
@@ -69,7 +66,7 @@ static bool surface_intersect_output(struct wlr_surface *surface,
69 } 66 }
70 67
71 struct wlr_box layout_box = { 68 struct wlr_box layout_box = {
72 .x = lx, .y = ly, 69 .x = wlr_output->lx + ox, .y = wlr_output->ly + oy,
73 .width = surface->current->width, .height = surface->current->height, 70 .width = surface->current->width, .height = surface->current->height,
74 }; 71 };
75 wlr_box_rotated_bounds(&layout_box, rotation, &layout_box); 72 wlr_box_rotated_bounds(&layout_box, rotation, &layout_box);
@@ -78,7 +75,7 @@ static bool surface_intersect_output(struct wlr_surface *surface,
78 75
79static void render_surface(struct wlr_surface *surface, 76static void render_surface(struct wlr_surface *surface,
80 struct wlr_output *wlr_output, struct timespec *when, 77 struct wlr_output *wlr_output, struct timespec *when,
81 double lx, double ly, float rotation) { 78 double ox, double oy, float rotation) {
82 struct wlr_renderer *renderer = 79 struct wlr_renderer *renderer =
83 wlr_backend_get_renderer(wlr_output->backend); 80 wlr_backend_get_renderer(wlr_output->backend);
84 81
@@ -90,7 +87,7 @@ static void render_surface(struct wlr_surface *surface,
90 87
91 struct wlr_box box; 88 struct wlr_box box;
92 bool intersects = surface_intersect_output(surface, layout, wlr_output, 89 bool intersects = surface_intersect_output(surface, layout, wlr_output,
93 lx, ly, rotation, &box); 90 ox, oy, rotation, &box);
94 if (intersects) { 91 if (intersects) {
95 float matrix[9]; 92 float matrix[9];
96 enum wl_output_transform transform = 93 enum wl_output_transform transform =
@@ -113,7 +110,7 @@ static void render_surface(struct wlr_surface *surface,
113 surface->current->width, surface->current->height, rotation); 110 surface->current->width, surface->current->height, rotation);
114 111
115 render_surface(subsurface->surface, wlr_output, when, 112 render_surface(subsurface->surface, wlr_output, when,
116 lx + sx, ly + sy, rotation); 113 ox + sx, oy + sy, rotation);
117 } 114 }
118} 115}
119 116
@@ -211,9 +208,7 @@ static void render_view(struct sway_container *view, void *data) {
211 } 208 }
212} 209}
213 210
214static void render_layer(struct sway_output *output, 211static void render_layer(struct sway_output *output, struct timespec *when,
215 const struct wlr_box *output_layout_box,
216 struct timespec *when,
217 struct wl_list *layer) { 212 struct wl_list *layer) {
218 struct sway_layer_surface *sway_layer; 213 struct sway_layer_surface *sway_layer;
219 wl_list_for_each(sway_layer, layer, link) { 214 wl_list_for_each(sway_layer, layer, link) {
@@ -245,14 +240,15 @@ static void render_output(struct sway_output *output, struct timespec *when,
245 float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; 240 float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
246 wlr_renderer_clear(renderer, clear_color); 241 wlr_renderer_clear(renderer, clear_color);
247 242
248 struct wlr_output_layout *layout = root_container.sway_root->output_layout; 243 struct wlr_output_layout *output_layout =
244 root_container.sway_root->output_layout;
249 const struct wlr_box *output_box = 245 const struct wlr_box *output_box =
250 wlr_output_layout_get_box(layout, wlr_output); 246 wlr_output_layout_get_box(output_layout, wlr_output);
251 247
252 render_layer(output, output_box, when, 248 render_layer(output, when,
253 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); 249 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
254 render_layer(output, output_box, when, 250 render_layer(output, when,
255 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); 251 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
256 252
257 struct sway_seat *seat = input_manager_current_seat(input_manager); 253 struct sway_seat *seat = input_manager_current_seat(input_manager);
258 struct sway_container *focus = 254 struct sway_container *focus =
@@ -262,7 +258,7 @@ static void render_output(struct sway_output *output, struct timespec *when,
262 focus = output->swayc->children->items[0]; 258 focus = output->swayc->children->items[0];
263 } 259 }
264 struct sway_container *workspace = focus->type == C_WORKSPACE ? 260 struct sway_container *workspace = focus->type == C_WORKSPACE ?
265 focus : container_parent(focus, C_WORKSPACE); 261 focus : container_parent(focus, C_WORKSPACE);
266 262
267 struct render_data rdata = { 263 struct render_data rdata = {
268 .output = output, 264 .output = output,
@@ -296,10 +292,10 @@ static void render_output(struct sway_output *output, struct timespec *when,
296 } 292 }
297 293
298 // TODO: Consider revising this when fullscreen windows are supported 294 // TODO: Consider revising this when fullscreen windows are supported
299 render_layer(output, output_box, when, 295 render_layer(output, when,
300 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); 296 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
301 render_layer(output, output_box, when, 297 render_layer(output, when,
302 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); 298 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
303 299
304renderer_end: 300renderer_end:
305 wlr_renderer_end(renderer); 301 wlr_renderer_end(renderer);
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 97b4473c..9229e92d 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -180,13 +180,18 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) {
180 double sx, sy; 180 double sx, sy;
181 struct sway_container *cont = 181 struct sway_container *cont =
182 container_at_cursor(cursor, &surface, &sx, &sy); 182 container_at_cursor(cursor, &surface, &sx, &sy);
183 if (surface && wlr_surface_is_layer_surface(surface)) {
184 struct wlr_layer_surface *layer =
185 wlr_layer_surface_from_wlr_surface(surface);
186 if (layer->current.keyboard_interactive) {
187 seat_set_focus_layer(cursor->seat, layer);
188 return;
189 }
190 }
183 // Avoid moving keyboard focus from a surface that accepts it to one 191 // Avoid moving keyboard focus from a surface that accepts it to one
184 // that does not unless the change would move us to a new workspace. 192 // that does not unless the change would move us to a new workspace.
185 // 193 //
186 // This prevents, for example, losing focus when clicking on swaybar. 194 // This prevents, for example, losing focus when clicking on swaybar.
187 //
188 // TODO: Replace this condition with something like
189 // !surface_accepts_keyboard_input
190 if (surface && cont && cont->type != C_VIEW) { 195 if (surface && cont && cont->type != C_VIEW) {
191 struct sway_container *new_ws = cont; 196 struct sway_container *new_ws = cont;
192 if (new_ws && new_ws->type != C_WORKSPACE) { 197 if (new_ws && new_ws->type != C_WORKSPACE) {
diff --git a/sway/input/seat.c b/sway/input/seat.c
index c326f176..4a99e9eb 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -352,8 +352,11 @@ void seat_configure_xcursor(struct sway_seat *seat) {
352 352
353void seat_set_focus_warp(struct sway_seat *seat, 353void seat_set_focus_warp(struct sway_seat *seat,
354 struct sway_container *container, bool warp) { 354 struct sway_container *container, bool warp) {
355 struct sway_container *last_focus = seat_get_focus(seat); 355 if (seat->focused_layer) {
356 return;
357 }
356 358
359 struct sway_container *last_focus = seat_get_focus(seat);
357 if (container && last_focus == container) { 360 if (container && last_focus == container) {
358 return; 361 return;
359 } 362 }
@@ -419,6 +422,37 @@ void seat_set_focus(struct sway_seat *seat,
419 seat_set_focus_warp(seat, container, true); 422 seat_set_focus_warp(seat, container, true);
420} 423}
421 424
425void seat_set_focus_layer(struct sway_seat *seat,
426 struct wlr_layer_surface *layer) {
427 if (!layer) {
428 seat->focused_layer = NULL;
429 return;
430 }
431 if (seat->focused_layer == layer) {
432 return;
433 }
434 if (seat->has_focus) {
435 struct sway_container *focus = seat_get_focus(seat);
436 if (focus->type == C_VIEW) {
437 wlr_seat_keyboard_clear_focus(seat->wlr_seat);
438 view_set_activated(focus->sway_view, false);
439 }
440 }
441 if (layer->layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
442 seat->focused_layer = layer;
443 }
444 struct wlr_keyboard *keyboard =
445 wlr_seat_get_keyboard(seat->wlr_seat);
446 if (keyboard) {
447 wlr_seat_keyboard_notify_enter(seat->wlr_seat,
448 layer->surface, keyboard->keycodes,
449 keyboard->num_keycodes, &keyboard->modifiers);
450 } else {
451 wlr_seat_keyboard_notify_enter(seat->wlr_seat,
452 layer->surface, NULL, 0, NULL);
453 }
454}
455
422struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, 456struct sway_container *seat_get_focus_inactive(struct sway_seat *seat,
423 struct sway_container *container) { 457 struct sway_container *container) {
424 return seat_get_focus_by_type(seat, container, C_TYPES); 458 return seat_get_focus_by_type(seat, container, C_TYPES);
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index a46359bd..5abdbc32 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -18,10 +18,14 @@
18 18
19struct sway_container root_container; 19struct sway_container root_container;
20 20
21static void output_layout_change_notify(struct wl_listener *listener, 21static void output_layout_handle_change(struct wl_listener *listener,
22 void *data) { 22 void *data) {
23 struct wlr_box *layout_box = wlr_output_layout_get_box( 23 struct wlr_output_layout *output_layout =
24 root_container.sway_root->output_layout, NULL); 24 root_container.sway_root->output_layout;
25 const struct wlr_box *layout_box =
26 wlr_output_layout_get_box(output_layout, NULL);
27 root_container.x = layout_box->x;
28 root_container.y = layout_box->y;
25 root_container.width = layout_box->width; 29 root_container.width = layout_box->width;
26 root_container.height = layout_box->height; 30 root_container.height = layout_box->height;
27 31
@@ -33,8 +37,8 @@ static void output_layout_change_notify(struct wl_listener *listener,
33 } 37 }
34 struct sway_output *output = output_container->sway_output; 38 struct sway_output *output = output_container->sway_output;
35 39
36 struct wlr_box *output_box = wlr_output_layout_get_box( 40 const struct wlr_box *output_box =
37 root_container.sway_root->output_layout, output->wlr_output); 41 wlr_output_layout_get_box(output_layout, output->wlr_output);
38 if (!output_box) { 42 if (!output_box) {
39 continue; 43 continue;
40 } 44 }
@@ -74,7 +78,7 @@ void layout_init(void) {
74 wl_signal_init(&root_container.sway_root->events.new_container); 78 wl_signal_init(&root_container.sway_root->events.new_container);
75 79
76 root_container.sway_root->output_layout_change.notify = 80 root_container.sway_root->output_layout_change.notify =
77 output_layout_change_notify; 81 output_layout_handle_change;
78 wl_signal_add(&root_container.sway_root->output_layout->events.change, 82 wl_signal_add(&root_container.sway_root->output_layout->events.change,
79 &root_container.sway_root->output_layout_change); 83 &root_container.sway_root->output_layout_change);
80} 84}
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index 6ba3d973..316f01e4 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -139,6 +139,24 @@ char *workspace_next_name(const char *output_name) {
139 continue; 139 continue;
140 } 140 }
141 141
142 // If the command is workspace number <name>, isolate the name
143 if (strncmp(_target, "number ", strlen("number ")) == 0) {
144 size_t length = strlen(_target) - strlen("number ") + 1;
145 char *temp = malloc(length);
146 strncpy(temp, _target + strlen("number "), length - 1);
147 temp[length - 1] = '\0';
148 free(_target);
149 _target = temp;
150 wlr_log(L_DEBUG, "Isolated name from workspace number: '%s'", _target);
151
152 // Make sure the workspace number doesn't already exist
153 if (workspace_by_number(_target)) {
154 free(_target);
155 free(dup);
156 continue;
157 }
158 }
159
142 // Make sure that the workspace doesn't already exist 160 // Make sure that the workspace doesn't already exist
143 if (workspace_by_name(_target)) { 161 if (workspace_by_name(_target)) {
144 free(_target); 162 free(_target);