aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.builds/freebsd.yml2
-rw-r--r--common/pango.c3
-rw-r--r--meson.build31
-rw-r--r--sway/commands/workspace.c4
-rw-r--r--sway/desktop/layer_shell.c37
-rw-r--r--sway/desktop/output.c7
-rw-r--r--sway/desktop/xwayland.c4
-rw-r--r--sway/input/cursor.c6
-rw-r--r--sway/input/seatop_default.c6
-rw-r--r--sway/input/tablet.c2
-rw-r--r--sway/tree/view.c2
-rw-r--r--sway/xdg_activation_v1.c12
12 files changed, 73 insertions, 43 deletions
diff --git a/.builds/freebsd.yml b/.builds/freebsd.yml
index 8084574c..977fe467 100644
--- a/.builds/freebsd.yml
+++ b/.builds/freebsd.yml
@@ -27,7 +27,7 @@ packages:
27- x11/libX11 27- x11/libX11
28- x11/pixman 28- x11/pixman
29- x11/xcb-util-wm 29- x11/xcb-util-wm
30- x11-servers/xwayland-devel 30- x11-servers/xwayland
31- misc/hwdata 31- misc/hwdata
32sources: 32sources:
33- https://github.com/swaywm/sway 33- https://github.com/swaywm/sway
diff --git a/common/pango.c b/common/pango.c
index 288569b3..e52b52b9 100644
--- a/common/pango.c
+++ b/common/pango.c
@@ -53,6 +53,8 @@ size_t escape_markup_text(const char *src, char *dest) {
53PangoLayout *get_pango_layout(cairo_t *cairo, const PangoFontDescription *desc, 53PangoLayout *get_pango_layout(cairo_t *cairo, const PangoFontDescription *desc,
54 const char *text, double scale, bool markup) { 54 const char *text, double scale, bool markup) {
55 PangoLayout *layout = pango_cairo_create_layout(cairo); 55 PangoLayout *layout = pango_cairo_create_layout(cairo);
56 pango_context_set_round_glyph_positions(pango_layout_get_context(layout), false);
57
56 PangoAttrList *attrs; 58 PangoAttrList *attrs;
57 if (markup) { 59 if (markup) {
58 char *buf; 60 char *buf;
@@ -104,6 +106,7 @@ void get_text_size(cairo_t *cairo, const PangoFontDescription *desc, int *width,
104void get_text_metrics(const PangoFontDescription *description, int *height, int *baseline) { 106void get_text_metrics(const PangoFontDescription *description, int *height, int *baseline) {
105 cairo_t *cairo = cairo_create(NULL); 107 cairo_t *cairo = cairo_create(NULL);
106 PangoContext *pango = pango_cairo_create_context(cairo); 108 PangoContext *pango = pango_cairo_create_context(cairo);
109 pango_context_set_round_glyph_positions(pango, false);
107 // When passing NULL as a language, pango uses the current locale. 110 // When passing NULL as a language, pango uses the current locale.
108 PangoFontMetrics *metrics = pango_context_get_metrics(pango, description, NULL); 111 PangoFontMetrics *metrics = pango_context_get_metrics(pango, description, NULL);
109 112
diff --git a/meson.build b/meson.build
index c602d008..0d5b0cc6 100644
--- a/meson.build
+++ b/meson.build
@@ -3,7 +3,7 @@ project(
3 'c', 3 'c',
4 version: '1.10-dev', 4 version: '1.10-dev',
5 license: 'MIT', 5 license: 'MIT',
6 meson_version: '>=0.60.0', 6 meson_version: '>=1.3',
7 default_options: [ 7 default_options: [
8 'c_std=c11', 8 'c_std=c11',
9 'warning_level=2', 9 'warning_level=2',
@@ -38,14 +38,14 @@ if is_freebsd
38endif 38endif
39 39
40# Execute the wlroots subproject, if any 40# Execute the wlroots subproject, if any
41wlroots_version = ['>=0.18.0', '<0.19.0'] 41wlroots_version = ['>=0.19.0', '<0.20.0']
42subproject( 42subproject(
43 'wlroots', 43 'wlroots',
44 default_options: ['examples=false'], 44 default_options: ['examples=false'],
45 required: false, 45 required: false,
46 version: wlroots_version, 46 version: wlroots_version,
47) 47)
48wlroots = dependency('wlroots-0.18', version: wlroots_version, fallback: 'wlroots') 48wlroots = dependency('wlroots-0.19', version: wlroots_version, fallback: 'wlroots')
49wlroots_features = { 49wlroots_features = {
50 'xwayland': false, 50 'xwayland': false,
51 'libinput_backend': false, 51 'libinput_backend': false,
@@ -172,31 +172,10 @@ if git.found()
172endif 172endif
173add_project_arguments('-DSWAY_VERSION=@0@'.format(version), language: 'c') 173add_project_arguments('-DSWAY_VERSION=@0@'.format(version), language: 'c')
174 174
175# Compute the relative path used by compiler invocations. 175fs = import('fs')
176source_root = meson.current_source_dir().split('/')
177build_root = meson.global_build_root().split('/')
178relative_dir_parts = []
179i = 0
180in_prefix = true
181foreach p : build_root
182 if i >= source_root.length() or not in_prefix or p != source_root[i]
183 in_prefix = false
184 relative_dir_parts += '..'
185 endif
186 i += 1
187endforeach
188i = 0
189in_prefix = true
190foreach p : source_root
191 if i >= build_root.length() or not in_prefix or build_root[i] != p
192 in_prefix = false
193 relative_dir_parts += p
194 endif
195 i += 1
196endforeach
197relative_dir = join_paths(relative_dir_parts) + '/'
198 176
199# Strip relative path prefixes from the code if possible, otherwise hide them. 177# Strip relative path prefixes from the code if possible, otherwise hide them.
178relative_dir = fs.relative_to(meson.current_source_dir(), meson.global_build_root()) + '/'
200if cc.has_argument('-fmacro-prefix-map=/prefix/to/hide=') 179if cc.has_argument('-fmacro-prefix-map=/prefix/to/hide=')
201 add_project_arguments( 180 add_project_arguments(
202 '-fmacro-prefix-map=@0@='.format(relative_dir), 181 '-fmacro-prefix-map=@0@='.format(relative_dir),
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c
index a14ebb20..37a201b4 100644
--- a/sway/commands/workspace.c
+++ b/sway/commands/workspace.c
@@ -157,6 +157,10 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
157 return cmd_results_new(CMD_FAILURE, 157 return cmd_results_new(CMD_FAILURE,
158 "Unable to allocate workspace output"); 158 "Unable to allocate workspace output");
159 } 159 }
160 if (output_location + 1 < argc) {
161 list_free_items_and_destroy(wsc->outputs);
162 wsc->outputs = create_list();
163 }
160 for (int i = output_location + 1; i < argc; ++i) { 164 for (int i = output_location + 1; i < argc; ++i) {
161 list_add(wsc->outputs, strdup(argv[i])); 165 list_add(wsc->outputs, strdup(argv[i]));
162 } 166 }
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c
index 6221b7b9..b136a24e 100644
--- a/sway/desktop/layer_shell.c
+++ b/sway/desktop/layer_shell.c
@@ -90,6 +90,43 @@ void arrange_layers(struct sway_output *output) {
90 } else { 90 } else {
91 arrange_popups(root->layers.popup); 91 arrange_popups(root->layers.popup);
92 } 92 }
93
94 // Find topmost keyboard interactive layer, if such a layer exists
95 struct wlr_scene_tree *layers_above_shell[] = {
96 output->layers.shell_overlay,
97 output->layers.shell_top,
98 };
99 size_t nlayers = sizeof(layers_above_shell) / sizeof(layers_above_shell[0]);
100 struct wlr_scene_node *node;
101 struct sway_layer_surface *topmost = NULL;
102 for (size_t i = 0; i < nlayers; ++i) {
103 wl_list_for_each_reverse(node,
104 &layers_above_shell[i]->children, link) {
105 struct sway_layer_surface *surface = scene_descriptor_try_get(node,
106 SWAY_SCENE_DESC_LAYER_SHELL);
107 if (surface && surface->layer_surface->current.keyboard_interactive
108 == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE &&
109 surface->layer_surface->surface->mapped) {
110 topmost = surface;
111 break;
112 }
113 }
114 if (topmost != NULL) {
115 break;
116 }
117 }
118
119 struct sway_seat *seat;
120 wl_list_for_each(seat, &server.input->seats, link) {
121 seat->has_exclusive_layer = false;
122 if (topmost != NULL) {
123 seat_set_focus_layer(seat, topmost->layer_surface);
124 } else if (seat->focused_layer &&
125 seat->focused_layer->current.keyboard_interactive
126 != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) {
127 seat_set_focus_layer(seat, NULL);
128 }
129 }
93} 130}
94 131
95static struct wlr_scene_tree *sway_layer_get_scene(struct sway_output *output, 132static struct wlr_scene_tree *sway_layer_get_scene(struct sway_output *output,
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index f936b2a8..27ede68e 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -247,6 +247,13 @@ static int output_repaint_timer_handler(void *data) {
247 .color_transform = output->color_transform, 247 .color_transform = output->color_transform,
248 }; 248 };
249 249
250 struct wlr_output *wlr_output = output->wlr_output;
251 struct wlr_scene_output *scene_output = output->scene_output;
252 if (!wlr_output->needs_frame && !output->gamma_lut_changed &&
253 !pixman_region32_not_empty(&scene_output->pending_commit_damage)) {
254 return 0;
255 }
256
250 struct wlr_output_state pending; 257 struct wlr_output_state pending;
251 wlr_output_state_init(&pending); 258 wlr_output_state_init(&pending);
252 if (!wlr_scene_output_build_state(output->scene_output, &pending, &opts)) { 259 if (!wlr_scene_output_build_state(output->scene_output, &pending, &opts)) {
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 270cf08f..0d45543a 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -71,7 +71,7 @@ static void unmanaged_handle_map(struct wl_listener *listener, void *data) {
71 surface->set_geometry.notify = unmanaged_handle_set_geometry; 71 surface->set_geometry.notify = unmanaged_handle_set_geometry;
72 } 72 }
73 73
74 if (wlr_xwayland_or_surface_wants_focus(xsurface)) { 74 if (wlr_xwayland_surface_override_redirect_wants_focus(xsurface)) {
75 struct sway_seat *seat = input_manager_current_seat(); 75 struct sway_seat *seat = input_manager_current_seat();
76 struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland; 76 struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland;
77 wlr_xwayland_set_seat(xwayland, seat->wlr_seat); 77 wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
@@ -96,7 +96,7 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) {
96 // This simply returns focus to the parent surface if there's one available. 96 // This simply returns focus to the parent surface if there's one available.
97 // This seems to handle JetBrains issues. 97 // This seems to handle JetBrains issues.
98 if (xsurface->parent && xsurface->parent->surface 98 if (xsurface->parent && xsurface->parent->surface
99 && wlr_xwayland_or_surface_wants_focus(xsurface->parent)) { 99 && wlr_xwayland_surface_override_redirect_wants_focus(xsurface->parent)) {
100 seat_set_focus_surface(seat, xsurface->parent->surface, false); 100 seat_set_focus_surface(seat, xsurface->parent->surface, false);
101 return; 101 return;
102 } 102 }
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 235951d4..bbd16717 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -578,7 +578,7 @@ static void handle_tablet_tool_position(struct sway_cursor *cursor,
578 // tablet events until the drag is released, even if we are now over a 578 // tablet events until the drag is released, even if we are now over a
579 // non-tablet surface. 579 // non-tablet surface.
580 if (!cursor->simulating_pointer_from_tool_tip && 580 if (!cursor->simulating_pointer_from_tool_tip &&
581 ((surface && wlr_surface_accepts_tablet_v2(tablet->tablet_v2, surface)) || 581 ((surface && wlr_surface_accepts_tablet_v2(surface, tablet->tablet_v2)) ||
582 wlr_tablet_tool_v2_has_implicit_grab(tool->tablet_v2_tool))) { 582 wlr_tablet_tool_v2_has_implicit_grab(tool->tablet_v2_tool))) {
583 seatop_tablet_tool_motion(seat, tool, time_msec); 583 seatop_tablet_tool_motion(seat, tool, time_msec);
584 } else { 584 } else {
@@ -664,7 +664,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
664 dispatch_cursor_button(cursor, &event->tablet->base, event->time_msec, 664 dispatch_cursor_button(cursor, &event->tablet->base, event->time_msec,
665 BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED); 665 BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED);
666 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); 666 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
667 } else if (!surface || !wlr_surface_accepts_tablet_v2(tablet_v2, surface)) { 667 } else if (!surface || !wlr_surface_accepts_tablet_v2(surface, tablet_v2)) {
668 // If we started holding the tool tip down on a surface that accepts 668 // If we started holding the tool tip down on a surface that accepts
669 // tablet v2, we should notify that surface if it gets released over a 669 // tablet v2, we should notify that surface if it gets released over a
670 // surface that doesn't support v2. 670 // surface that doesn't support v2.
@@ -749,7 +749,7 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
749 bool mod_pressed = modifiers & config->floating_mod; 749 bool mod_pressed = modifiers & config->floating_mod;
750 750
751 bool surface_supports_tablet_events = 751 bool surface_supports_tablet_events =
752 surface && wlr_surface_accepts_tablet_v2(tablet_v2, surface); 752 surface && wlr_surface_accepts_tablet_v2(surface, tablet_v2);
753 753
754 // Simulate pointer when: 754 // Simulate pointer when:
755 // 1. The modifier key is pressed, OR 755 // 1. The modifier key is pressed, OR
diff --git a/sway/input/seatop_default.c b/sway/input/seatop_default.c
index f4a0f463..42ce333b 100644
--- a/sway/input/seatop_default.c
+++ b/sway/input/seatop_default.c
@@ -273,7 +273,7 @@ static void handle_tablet_tool_tip(struct sway_seat *seat,
273 // Handle tapping on an xwayland unmanaged view 273 // Handle tapping on an xwayland unmanaged view
274 else if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(surface)) && 274 else if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(surface)) &&
275 xsurface->override_redirect && 275 xsurface->override_redirect &&
276 wlr_xwayland_or_surface_wants_focus(xsurface)) { 276 wlr_xwayland_surface_override_redirect_wants_focus(xsurface)) {
277 struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland; 277 struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland;
278 wlr_xwayland_set_seat(xwayland, seat->wlr_seat); 278 wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
279 seat_set_focus_surface(seat, xsurface->surface, false); 279 seat_set_focus_surface(seat, xsurface->surface, false);
@@ -521,7 +521,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
521 if (surface && 521 if (surface &&
522 (xsurface = wlr_xwayland_surface_try_from_wlr_surface(surface)) && 522 (xsurface = wlr_xwayland_surface_try_from_wlr_surface(surface)) &&
523 xsurface->override_redirect && 523 xsurface->override_redirect &&
524 wlr_xwayland_or_surface_wants_focus(xsurface)) { 524 wlr_xwayland_surface_override_redirect_wants_focus(xsurface)) {
525 struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland; 525 struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland;
526 wlr_xwayland_set_seat(xwayland, seat->wlr_seat); 526 wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
527 seat_set_focus_surface(seat, xsurface->surface, false); 527 seat_set_focus_surface(seat, xsurface->surface, false);
@@ -667,7 +667,7 @@ static void handle_touch_down(struct sway_seat *seat,
667 double sx, sy; 667 double sx, sy;
668 node_at_coords(seat, seat->touch_x, seat->touch_y, &surface, &sx, &sy); 668 node_at_coords(seat, seat->touch_x, seat->touch_y, &surface, &sx, &sy);
669 669
670 if (surface && wlr_surface_accepts_touch(wlr_seat, surface)) { 670 if (surface && wlr_surface_accepts_touch(surface, wlr_seat)) {
671 if (seat_is_input_allowed(seat, surface)) { 671 if (seat_is_input_allowed(seat, surface)) {
672 cursor->simulating_pointer_from_touch = false; 672 cursor->simulating_pointer_from_touch = false;
673 seatop_begin_touch_down(seat, surface, event, sx, sy, lx, ly); 673 seatop_begin_touch_down(seat, surface, event, sx, sy, lx, ly);
diff --git a/sway/input/tablet.c b/sway/input/tablet.c
index ec1e4f68..19d5debf 100644
--- a/sway/input/tablet.c
+++ b/sway/input/tablet.c
@@ -363,7 +363,7 @@ void sway_tablet_pad_set_focus(struct sway_tablet_pad *tablet_pad,
363 } 363 }
364 364
365 if (surface == NULL || 365 if (surface == NULL ||
366 !wlr_surface_accepts_tablet_v2(tablet_pad->tablet->tablet_v2, surface)) { 366 !wlr_surface_accepts_tablet_v2(surface, tablet_pad->tablet->tablet_v2)) {
367 return; 367 return;
368 } 368 }
369 369
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 4f757acf..229d765e 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -850,7 +850,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
850#if WLR_HAS_XWAYLAND 850#if WLR_HAS_XWAYLAND
851 struct wlr_xwayland_surface *xsurface; 851 struct wlr_xwayland_surface *xsurface;
852 if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(wlr_surface))) { 852 if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(wlr_surface))) {
853 set_focus &= wlr_xwayland_icccm_input_model(xsurface) != 853 set_focus &= wlr_xwayland_surface_icccm_input_model(xsurface) !=
854 WLR_ICCCM_INPUT_MODEL_NONE; 854 WLR_ICCCM_INPUT_MODEL_NONE;
855 } 855 }
856#endif 856#endif
diff --git a/sway/xdg_activation_v1.c b/sway/xdg_activation_v1.c
index b7c80dd4..fd604874 100644
--- a/sway/xdg_activation_v1.c
+++ b/sway/xdg_activation_v1.c
@@ -38,14 +38,14 @@ void xdg_activation_v1_handle_request_activate(struct wl_listener *listener,
38 } 38 }
39 39
40 // This is an activation request. If this context is internal we have ctx->seat. 40 // This is an activation request. If this context is internal we have ctx->seat.
41 struct sway_seat *seat = ctx->seat; 41 if (ctx->seat) {
42 if (!seat) { 42 view_request_activate(view, ctx->seat);
43 // Otherwise, use the seat indicated by the launcher client in set_serial 43 return;
44 seat = ctx->token->seat ? ctx->token->seat->data : NULL;
45 } 44 }
46 45
47 if (seat && ctx->had_focused_surface) { 46 // Otherwise, activate if passed from another focused client
48 view_request_activate(view, seat); 47 if (ctx->token->seat && ctx->had_focused_surface) {
48 view_request_activate(view, ctx->token->seat->data);
49 } else { 49 } else {
50 // The token is valid, but cannot be used to activate a window 50 // The token is valid, but cannot be used to activate a window
51 view_request_urgent(view); 51 view_request_urgent(view);