diff options
-rw-r--r-- | .builds/freebsd.yml | 2 | ||||
-rw-r--r-- | common/pango.c | 3 | ||||
-rw-r--r-- | meson.build | 31 | ||||
-rw-r--r-- | sway/commands/workspace.c | 4 | ||||
-rw-r--r-- | sway/desktop/layer_shell.c | 37 | ||||
-rw-r--r-- | sway/desktop/output.c | 7 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 4 | ||||
-rw-r--r-- | sway/input/cursor.c | 6 | ||||
-rw-r--r-- | sway/input/seatop_default.c | 6 | ||||
-rw-r--r-- | sway/input/tablet.c | 2 | ||||
-rw-r--r-- | sway/tree/view.c | 2 | ||||
-rw-r--r-- | sway/xdg_activation_v1.c | 12 |
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 |
32 | sources: | 32 | sources: |
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) { | |||
53 | PangoLayout *get_pango_layout(cairo_t *cairo, const PangoFontDescription *desc, | 53 | PangoLayout *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, | |||
104 | void get_text_metrics(const PangoFontDescription *description, int *height, int *baseline) { | 106 | void 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 | |||
38 | endif | 38 | endif |
39 | 39 | ||
40 | # Execute the wlroots subproject, if any | 40 | # Execute the wlroots subproject, if any |
41 | wlroots_version = ['>=0.18.0', '<0.19.0'] | 41 | wlroots_version = ['>=0.19.0', '<0.20.0'] |
42 | subproject( | 42 | subproject( |
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 | ) |
48 | wlroots = dependency('wlroots-0.18', version: wlroots_version, fallback: 'wlroots') | 48 | wlroots = dependency('wlroots-0.19', version: wlroots_version, fallback: 'wlroots') |
49 | wlroots_features = { | 49 | wlroots_features = { |
50 | 'xwayland': false, | 50 | 'xwayland': false, |
51 | 'libinput_backend': false, | 51 | 'libinput_backend': false, |
@@ -172,31 +172,10 @@ if git.found() | |||
172 | endif | 172 | endif |
173 | add_project_arguments('-DSWAY_VERSION=@0@'.format(version), language: 'c') | 173 | add_project_arguments('-DSWAY_VERSION=@0@'.format(version), language: 'c') |
174 | 174 | ||
175 | # Compute the relative path used by compiler invocations. | 175 | fs = import('fs') |
176 | source_root = meson.current_source_dir().split('/') | ||
177 | build_root = meson.global_build_root().split('/') | ||
178 | relative_dir_parts = [] | ||
179 | i = 0 | ||
180 | in_prefix = true | ||
181 | foreach 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 | ||
187 | endforeach | ||
188 | i = 0 | ||
189 | in_prefix = true | ||
190 | foreach 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 | ||
196 | endforeach | ||
197 | relative_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. |
178 | relative_dir = fs.relative_to(meson.current_source_dir(), meson.global_build_root()) + '/' | ||
200 | if cc.has_argument('-fmacro-prefix-map=/prefix/to/hide=') | 179 | if 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 | ||
95 | static struct wlr_scene_tree *sway_layer_get_scene(struct sway_output *output, | 132 | static 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); |