aboutsummarylogtreecommitdiffstats
diff options
context:
space:
mode:
authortinywrkb2022-01-28 01:56:55 +0200
committerHyeon Kim2022-01-29 02:11:04 +0900
commit77318b93b258b9a9721ebb7fb2135b0291395b1d (patch)
tree3d1b082f7749f3ac37a74b20897e4a11cabcad21
parent171956a48da1411684d60144f4e72a0c8b4d139a (diff)
downloadaur-77318b93b258b9a9721ebb7fb2135b0291395b1d.tar.gz
sway-im: bump to 1.7-1, add input method v2 popups patch
Update to the latest stable release and add the input method v2 popups patch. The popups patch is the last bit that is missing for full IME frameworks support in Wayland. Currently, it doesn't look like wlroots changes will be needed, so I think it's better to stay on stable and just port back the patch, if needed, so _pkgver is gone. A minor issue that was fixed is the installation folder of the license. It should match the package name. This confirmed to be working with anthywl, though I'm not sure how well, as I don't really know how to type in Japanese. It doesn't seem to work with recent dev build of Fcitx5.
-rw-r--r--.SRCINFO19
-rw-r--r--0001-Implement-input-method-keyboard-grab.patch172
-rw-r--r--0001-text_input-Implement-input-method-popups.patch678
-rw-r--r--0002-im-Handle-text-disable-on-focus-lost-properly.patch29
-rw-r--r--50-systemd-user.conf4
-rw-r--r--PKGBUILD42
6 files changed, 707 insertions, 237 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 9957711cfccb..1473af42aa2c 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,6 +1,6 @@
pkgbase = sway-im
- pkgdesc = sway Wayland compositor with input method keyboard grab support
- pkgver = 1.5.1.r2.ec36e113
+ pkgdesc = Tiling Wayland compositor and replacement for the i3 window manager, with input method popups v2 support
+ pkgver = 1.7
pkgrel = 1
epoch = 1
url = https://swaywm.org/
@@ -21,7 +21,6 @@ pkgbase = sway-im
depends = swaybg
depends = ttf-font
depends = wlroots
- optdepends = alacritty: Terminal emulator used by the default config
optdepends = dmenu: Application launcher
optdepends = grim: Screenshot utility
optdepends = i3status: Status line
@@ -35,17 +34,15 @@ pkgbase = sway-im
provides = sway
conflicts = sway
backup = etc/sway/config
- source = https://github.com/swaywm/sway/releases/download/1.5.1/sway-1.5.1.tar.gz
- source = https://github.com/swaywm/sway/releases/download/1.5.1/sway-1.5.1.tar.gz.sig
- source = 0001-Implement-input-method-keyboard-grab.patch
- source = 0002-im-Handle-text-disable-on-focus-lost-properly.patch
+ source = https://github.com/swaywm/sway/releases/download/1.7/sway-1.7.tar.gz
+ source = https://github.com/swaywm/sway/releases/download/1.7/sway-1.7.tar.gz.sig
source = 50-systemd-user.conf
+ source = 0001-text_input-Implement-input-method-popups.patch
validpgpkeys = 34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48
validpgpkeys = 9DDA3B9FA5D58DD5392C78E652CB6609B22DA89A
- sha512sums = 3b937249db2875100bc22e99f955a3300d3294a296fb37006fa1468a3986bf4fa8e5197279e3587bd8dc29f31adff8fbdc9ddc840e7be982b73331a05cd06ba5
+ sha512sums = 028cf5d504d5914bfb78d44156d6a290de660c5ed0638f4e2c56e5be76db9b0baeda035e1fa1ae23559016bd7e4312f7ff70c2fb4904df25358577c1a3d21243
sha512sums = SKIP
- sha512sums = d1cad32660f7a39cac423808f96c3253355a657ffc466617a68e574d02b2d47016bdeb32a3a496a95fe5a75fb132903f4b551b55eae7641cc881be68be2e52e9
- sha512sums = 3bbdef63985980ce52caf51aa141cdd619fb055c2ba199e783666da779e4ae38c4338ddad37ba29ea8a0c11b0c692834c1c4a00d5260c4dc09c041b5d6bc6253
- sha512sums = 57590bc0d14c87289a4a9cd67991c6a841e54244d2a6186b5da5a08e633de2e8631959fa8c77ede211b0a5f315d920f2c1350951a53d6f2e9e81859056cb3c9e
+ sha512sums = c2b7d808f4231f318e03789015624fd4cf32b81434b15406570b4e144c0defc54e216d881447e6fd9fc18d7da608cccb61c32e0e1fab2f1fe2750acf812d3137
+ sha512sums = b39325808c7327c47d3f024d355392387b65240f86d5391eafd9b52c70d89cb50192a58f3bac954abc90430806b73799a664c558e12fcdcf23529b77752c14cd
pkgname = sway-im
diff --git a/0001-Implement-input-method-keyboard-grab.patch b/0001-Implement-input-method-keyboard-grab.patch
deleted file mode 100644
index 2829757fa791..000000000000
--- a/0001-Implement-input-method-keyboard-grab.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From 0ed4486050b5ac7ae28b8499c68770ea0ff2f44e Mon Sep 17 00:00:00 2001
-From: xdavidwu <xdavidwuph@gmail.com>
-Date: Tue, 21 Jan 2020 11:25:39 +0800
-Subject: [PATCH 1/2] Implement input-method keyboard grab
-
-Reference:
- https://github.com/swaywm/sway/pull/4932
----
- include/sway/input/text_input.h | 3 ++
- sway/input/keyboard.c | 64 ++++++++++++++++++++++++++++++---
- sway/input/text_input.c | 34 ++++++++++++++++++
- 3 files changed, 97 insertions(+), 4 deletions(-)
-
-diff --git a/include/sway/input/text_input.h b/include/sway/input/text_input.h
-index 81915795..447f761a 100644
---- a/include/sway/input/text_input.h
-+++ b/include/sway/input/text_input.h
-@@ -28,7 +28,10 @@ struct sway_input_method_relay {
-
- struct wl_listener input_method_new;
- struct wl_listener input_method_commit;
-+ struct wl_listener input_method_grab_keyboard;
- struct wl_listener input_method_destroy;
-+
-+ struct wl_listener input_method_keyboard_grab_destroy;
- };
-
- struct sway_text_input {
-diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c
-index 541fc90d..696b8fb8 100644
---- a/sway/input/keyboard.c
-+++ b/sway/input/keyboard.c
-@@ -485,6 +485,40 @@ static void handle_key_event(struct sway_keyboard *keyboard,
- }
-
- if (!handled || event->state == WLR_KEY_RELEASED) {
-+ if (seat->im_relay.input_method) {
-+ struct wlr_input_method_keyboard_grab_v2 *kb_grab =
-+ seat->im_relay.input_method->keyboard_grab;
-+ struct wlr_virtual_keyboard_v1 *virtual_keyboard =
-+ wlr_input_device_get_virtual_keyboard(wlr_device);
-+
-+ // If event is from virtual keyboard of the same client as grab,
-+ // do not send it back. TODO see swaywm/wlroots#2322
-+ if (kb_grab && !(virtual_keyboard &&
-+ wl_resource_get_client(virtual_keyboard->resource) ==
-+ wl_resource_get_client(kb_grab->resource))) {
-+ // Do not send release event to grab if the press event was not
-+ // sent to grab.
-+ if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
-+ bool pressed_sent = update_shortcut_state(
-+ &keyboard->state_pressed_sent, event->keycode,
-+ event->state, keyinfo.keycode, 0);
-+ if (pressed_sent) {
-+ wlr_seat_set_keyboard(wlr_seat, wlr_device);
-+ wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec,
-+ event->keycode, event->state);
-+ goto end;
-+ }
-+
-+ }
-+
-+ wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab,
-+ wlr_device->keyboard);
-+ wlr_input_method_keyboard_grab_v2_send_key(kb_grab,
-+ event->time_msec, event->keycode, event->state);
-+ goto end;
-+ }
-+ }
-+
- bool pressed_sent = update_shortcut_state(
- &keyboard->state_pressed_sent, event->keycode, event->state,
- keyinfo.keycode, 0);
-@@ -495,6 +529,7 @@ static void handle_key_event(struct sway_keyboard *keyboard,
- }
- }
-
-+end:
- transaction_commit_dirty();
-
- free(device_identifier);
-@@ -612,10 +647,31 @@ static void handle_modifier_event(struct sway_keyboard *keyboard) {
- struct wlr_input_device *wlr_device =
- keyboard->seat_device->input_device->wlr_device;
- if (!wlr_device->keyboard->group) {
-- struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat;
-- wlr_seat_set_keyboard(wlr_seat, wlr_device);
-- wlr_seat_keyboard_notify_modifiers(wlr_seat,
-- &wlr_device->keyboard->modifiers);
-+ struct sway_seat *seat = keyboard->seat_device->sway_seat;
-+ bool sent_to_kb_grab = false;
-+ if (seat->im_relay.input_method) {
-+ struct wlr_input_method_keyboard_grab_v2 *kb_grab =
-+ seat->im_relay.input_method->keyboard_grab;
-+ struct wlr_virtual_keyboard_v1 *virtual_keyboard =
-+ wlr_input_device_get_virtual_keyboard(wlr_device);
-+
-+ // If event is from virtual keyboard of the same client as grab,
-+ // do not send it back. TODO see swaywm/wlroots#2322
-+ if (kb_grab && !(virtual_keyboard &&
-+ wl_resource_get_client(virtual_keyboard->resource) ==
-+ wl_resource_get_client(kb_grab->resource))) {
-+ wlr_input_method_keyboard_grab_v2_set_keyboard(kb_grab,
-+ wlr_device->keyboard);
-+ wlr_input_method_keyboard_grab_v2_send_modifiers(kb_grab,
-+ &wlr_device->keyboard->modifiers);
-+ sent_to_kb_grab = true;
-+ }
-+ }
-+ if (!sent_to_kb_grab) {
-+ wlr_seat_set_keyboard(seat->wlr_seat, wlr_device);
-+ wlr_seat_keyboard_notify_modifiers(seat->wlr_seat,
-+ &wlr_device->keyboard->modifiers);
-+ }
-
- uint32_t modifiers = wlr_keyboard_get_modifiers(wlr_device->keyboard);
- determine_bar_visibility(modifiers);
-diff --git a/sway/input/text_input.c b/sway/input/text_input.c
-index 2fb25eef..8a29f186 100644
---- a/sway/input/text_input.c
-+++ b/sway/input/text_input.c
-@@ -55,6 +55,37 @@ static void handle_im_commit(struct wl_listener *listener, void *data) {
- wlr_text_input_v3_send_done(text_input->input);
- }
-
-+static void handle_im_keyboard_grab_destroy(struct wl_listener *listener, void *data) {
-+ struct sway_input_method_relay *relay = wl_container_of(listener, relay,
-+ input_method_keyboard_grab_destroy);
-+ struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
-+ wl_list_remove(&relay->input_method_keyboard_grab_destroy.link);
-+
-+ if (keyboard_grab->keyboard) {
-+ // send modifier state to original client
-+ wlr_seat_keyboard_notify_modifiers(keyboard_grab->input_method->seat,
-+ &keyboard_grab->keyboard->modifiers);
-+ }
-+}
-+
-+static void handle_im_grab_keyboard(struct wl_listener *listener, void *data) {
-+ struct sway_input_method_relay *relay = wl_container_of(listener, relay,
-+ input_method_grab_keyboard);
-+ struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
-+
-+ // send modifier state to grab
-+ struct wlr_keyboard *active_keyboard = wlr_seat_get_keyboard(relay->seat->wlr_seat);
-+ wlr_input_method_keyboard_grab_v2_set_keyboard(keyboard_grab,
-+ active_keyboard);
-+ wlr_input_method_keyboard_grab_v2_send_modifiers(keyboard_grab,
-+ &active_keyboard->modifiers);
-+
-+ wl_signal_add(&keyboard_grab->events.destroy,
-+ &relay->input_method_keyboard_grab_destroy);
-+ relay->input_method_keyboard_grab_destroy.notify =
-+ handle_im_keyboard_grab_destroy;
-+}
-+
- static void text_input_set_pending_focused_surface(
- struct sway_text_input *text_input, struct wlr_surface *surface) {
- wl_list_remove(&text_input->pending_focused_surface_destroy.link);
-@@ -236,6 +267,9 @@ static void relay_handle_input_method(struct wl_listener *listener,
- wl_signal_add(&relay->input_method->events.commit,
- &relay->input_method_commit);
- relay->input_method_commit.notify = handle_im_commit;
-+ wl_signal_add(&relay->input_method->events.grab_keyboard,
-+ &relay->input_method_grab_keyboard);
-+ relay->input_method_grab_keyboard.notify = handle_im_grab_keyboard;
- wl_signal_add(&relay->input_method->events.destroy,
- &relay->input_method_destroy);
- relay->input_method_destroy.notify = handle_im_destroy;
---
-2.30.0
-
diff --git a/0001-text_input-Implement-input-method-popups.patch b/0001-text_input-Implement-input-method-popups.patch
new file mode 100644
index 000000000000..c15bb20649a4
--- /dev/null
+++ b/0001-text_input-Implement-input-method-popups.patch
@@ -0,0 +1,678 @@
+From 9debeb40ceaeae9e577bddcc248a36d99f0a066f Mon Sep 17 00:00:00 2001
+From: Tadeo Kondrak <me@tadeo.ca>
+Date: Tue, 15 Dec 2020 21:24:57 -0700
+Subject: [PATCH] text_input: Implement input-method popups
+
+---
+ include/sway/input/text_input.h | 22 ++
+ include/sway/output.h | 4 +
+ sway/desktop/output.c | 26 +++
+ sway/desktop/render.c | 17 +-
+ sway/input/cursor.c | 27 +++
+ sway/input/text_input.c | 349 +++++++++++++++++++++++++++++++-
+ sway/tree/container.c | 2 +
+ sway/tree/view.c | 3 +
+ 8 files changed, 442 insertions(+), 8 deletions(-)
+
+diff --git a/include/sway/input/text_input.h b/include/sway/input/text_input.h
+index 37744266d9..1ed0c4d70e 100644
+--- a/include/sway/input/text_input.h
++++ b/include/sway/input/text_input.h
+@@ -22,18 +22,37 @@ struct sway_input_method_relay {
+ struct sway_seat *seat;
+
+ struct wl_list text_inputs; // sway_text_input::link
++ struct wl_list input_popups; // sway_input_popup::link
+ struct wlr_input_method_v2 *input_method; // doesn't have to be present
+
+ struct wl_listener text_input_new;
+
+ struct wl_listener input_method_new;
+ struct wl_listener input_method_commit;
++ struct wl_listener input_method_new_popup_surface;
+ struct wl_listener input_method_grab_keyboard;
+ struct wl_listener input_method_destroy;
+
+ struct wl_listener input_method_keyboard_grab_destroy;
+ };
+
++struct sway_input_popup {
++ struct sway_input_method_relay *relay;
++ struct wlr_input_popup_surface_v2 *popup_surface;
++
++ int x, y;
++ bool visible;
++
++ struct wl_list link;
++
++ struct wl_listener popup_map;
++ struct wl_listener popup_unmap;
++ struct wl_listener popup_destroy;
++ struct wl_listener popup_surface_commit;
++
++ struct wl_listener focused_surface_unmap;
++};
++
+ struct sway_text_input {
+ struct sway_input_method_relay *relay;
+
+@@ -66,4 +85,7 @@ struct sway_text_input *sway_text_input_create(
+ struct sway_input_method_relay *relay,
+ struct wlr_text_input_v3 *text_input);
+
++bool sway_input_popup_get_position(
++ struct sway_input_popup *popup, int *lx, int *ly);
++
+ #endif
+diff --git a/include/sway/output.h b/include/sway/output.h
+index 26b9709f98..5c6b0010c4 100644
+--- a/include/sway/output.h
++++ b/include/sway/output.h
+@@ -137,6 +137,10 @@ void output_unmanaged_for_each_surface(struct sway_output *output,
+ void *user_data);
+ #endif
+
++void output_input_popups_for_each_surface(struct sway_output *output,
++ struct wl_list *input_popups, sway_surface_iterator_func_t iterator,
++ void *user_data);
++
+ void output_drag_icons_for_each_surface(struct sway_output *output,
+ struct wl_list *drag_icons, sway_surface_iterator_func_t iterator,
+ void *user_data);
+diff --git a/sway/desktop/output.c b/sway/desktop/output.c
+index 68f095c044..46f3c3a7b2 100644
+--- a/sway/desktop/output.c
++++ b/sway/desktop/output.c
+@@ -22,6 +22,7 @@
+ #include "sway/desktop/transaction.h"
+ #include "sway/input/input-manager.h"
+ #include "sway/input/seat.h"
++#include "sway/input/text_input.h"
+ #include "sway/layers.h"
+ #include "sway/output.h"
+ #include "sway/server.h"
+@@ -246,6 +247,28 @@ void output_unmanaged_for_each_surface(struct sway_output *output,
+ }
+ #endif
+
++void output_input_popups_for_each_surface(struct sway_output *output,
++ struct wl_list *input_popups, sway_surface_iterator_func_t iterator,
++ void *user_data) {
++ struct sway_input_popup *popup;
++ wl_list_for_each(popup, input_popups, link) {
++ int lx, ly;
++ if (!sway_input_popup_get_position(popup, &lx, &ly)) {
++ continue;
++ }
++ if (!popup->popup_surface->mapped || !popup->visible) {
++ continue;
++ }
++
++ double ox = lx - output->lx;
++ double oy = ly - output->ly;
++
++ output_surface_for_each_surface(output,
++ popup->popup_surface->surface, ox, oy,
++ iterator, user_data);
++ }
++}
++
+ void output_drag_icons_for_each_surface(struct sway_output *output,
+ struct wl_list *drag_icons, sway_surface_iterator_func_t iterator,
+ void *user_data) {
+@@ -337,6 +360,9 @@ static void output_for_each_surface(struct sway_output *output,
+ output_layer_for_each_surface(output,
+ &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
+ iterator, user_data);
++ output_input_popups_for_each_surface(
++ output, &input_manager_current_seat()->im_relay.input_popups,
++ iterator, user_data);
+ output_drag_icons_for_each_surface(output, &root->drag_icons,
+ iterator, user_data);
+ }
+diff --git a/sway/desktop/render.c b/sway/desktop/render.c
+index c088c936dc..2fc14dd2ff 100644
+--- a/sway/desktop/render.c
++++ b/sway/desktop/render.c
+@@ -19,6 +19,7 @@
+ #include "sway/config.h"
+ #include "sway/input/input-manager.h"
+ #include "sway/input/seat.h"
++#include "sway/input/text_input.h"
+ #include "sway/layers.h"
+ #include "sway/output.h"
+ #include "sway/server.h"
+@@ -201,6 +202,16 @@ static void render_unmanaged(struct sway_output *output,
+ }
+ #endif
+
++static void render_input_popups(struct sway_output *output,
++ pixman_region32_t *damage, struct wl_list *input_popups) {
++ struct render_data data = {
++ .damage = damage,
++ .alpha = 1.0f,
++ };
++ output_input_popups_for_each_surface(output, input_popups,
++ render_surface_iterator, &data);
++}
++
+ static void render_drag_icons(struct sway_output *output,
+ pixman_region32_t *damage, struct wl_list *drag_icons) {
+ struct render_data data = {
+@@ -1029,6 +1040,9 @@ void output_render(struct sway_output *output, struct timespec *when,
+ struct wlr_output *wlr_output = output->wlr_output;
+ struct wlr_renderer *renderer = output->server->renderer;
+
++ struct sway_seat *seat = input_manager_current_seat();
++ struct sway_container *focus = seat_get_focused_container(seat);
++
+ struct sway_workspace *workspace = output->current.active_workspace;
+ if (workspace == NULL) {
+ return;
+@@ -1125,8 +1139,6 @@ void output_render(struct sway_output *output, struct timespec *when,
+
+ render_seatops(output, damage);
+
+- struct sway_seat *seat = input_manager_current_seat();
+- struct sway_container *focus = seat_get_focused_container(seat);
+ if (focus && focus->view) {
+ render_view_popups(focus->view, output, damage, focus->alpha);
+ }
+@@ -1136,6 +1148,7 @@ void output_render(struct sway_output *output, struct timespec *when,
+ &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
+ render_layer_popups(output, damage,
+ &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
++ render_input_popups(output, damage, &seat->im_relay.input_popups);
+ render_drag_icons(output, damage, &root->drag_icons);
+
+ renderer_end:
+diff --git a/sway/input/cursor.c b/sway/input/cursor.c
+index d8b1abeb46..87a8d7c5d6 100644
+--- a/sway/input/cursor.c
++++ b/sway/input/cursor.c
+@@ -37,6 +37,28 @@ static uint32_t get_current_time_msec(void) {
+ return now.tv_sec * 1000 + now.tv_nsec / 1000000;
+ }
+
++static struct wlr_surface *input_popup_surface_at(struct sway_output *output,
++ struct sway_input_method_relay *relay, double ox, double oy, double *sx, double *sy) {
++ struct sway_input_popup *popup;
++ wl_list_for_each(popup, &relay->input_popups, link) {
++ int lx, ly;
++ if (!sway_input_popup_get_position(popup, &lx, &ly)) {
++ continue;
++ }
++ if (!popup->popup_surface->mapped || !popup->visible) {
++ continue;
++ }
++ double _sx = ox - lx;
++ double _sy = oy - ly;
++ struct wlr_surface *sub = wlr_surface_surface_at(
++ popup->popup_surface->surface, _sx, _sy, sx, sy);
++ if (sub) {
++ return sub;
++ }
++ }
++ return NULL;
++}
++
+ static struct wlr_surface *layer_surface_at(struct sway_output *output,
+ struct wl_list *layer, double ox, double oy, double *sx, double *sy) {
+ struct sway_layer_surface *sway_layer;
+@@ -139,6 +161,11 @@ struct sway_node *node_at_coords(
+ return NULL;
+ }
+
++ if ((*surface = input_popup_surface_at(output,
++ &seat->im_relay, ox, oy, sx, sy))) {
++ return NULL;
++ }
++
+ if (ws->fullscreen) {
+ // Try transient containers
+ for (int i = 0; i < ws->floating->length; ++i) {
+diff --git a/sway/input/text_input.c b/sway/input/text_input.c
+index b8c19c179e..6350b3f933 100644
+--- a/sway/input/text_input.c
++++ b/sway/input/text_input.c
+@@ -3,6 +3,11 @@
+ #include "log.h"
+ #include "sway/input/seat.h"
+ #include "sway/input/text_input.h"
++#include "sway/tree/view.h"
++#include "sway/tree/container.h"
++#include "sway/desktop.h"
++#include "sway/output.h"
++#include "sway/layers.h"
+
+ static struct sway_text_input *relay_get_focusable_text_input(
+ struct sway_input_method_relay *relay) {
+@@ -26,6 +31,329 @@ static struct sway_text_input *relay_get_focused_text_input(
+ return NULL;
+ }
+
++static void input_popup_damage(struct sway_input_popup *popup) {
++ if (!popup->popup_surface->mapped || !popup->visible) {
++ return;
++ }
++
++ struct sway_text_input *text_input =
++ relay_get_focused_text_input(popup->relay);
++ if (text_input == NULL || text_input->input->focused_surface == NULL) {
++ return;
++ }
++
++ struct wlr_surface *focused_surface = text_input->input->focused_surface;
++ if (wlr_surface_is_layer_surface(focused_surface)) {
++ struct wlr_layer_surface_v1 *layer_surface =
++ wlr_layer_surface_v1_from_wlr_surface(focused_surface);
++ struct sway_layer_surface *layer =
++ layer_from_wlr_layer_surface_v1(layer_surface);
++ output_damage_surface(layer->layer_surface->output->data,
++ layer->geo.x + popup->x, layer->geo.y + popup->y,
++ popup->popup_surface->surface, true);
++ return;
++ }
++
++ struct sway_view *view = view_from_wlr_surface(
++ text_input->input->focused_surface);
++ if (view->container == NULL) {
++ sway_log(SWAY_INFO, "Tried to damage popup, but view is gone");
++ return;
++ }
++ desktop_damage_surface(popup->popup_surface->surface,
++ view->container->surface_x - view->geometry.x + popup->x,
++ view->container->surface_y - view->geometry.y + popup->y, true);
++}
++
++static void input_popup_update(struct sway_input_popup *popup) {
++ input_popup_damage(popup);
++
++ struct sway_text_input *text_input =
++ relay_get_focused_text_input(popup->relay);
++
++ if (text_input == NULL || text_input->input->focused_surface == NULL) {
++ return;
++ }
++
++ if (!popup->popup_surface->mapped) {
++ return;
++ }
++
++ bool cursor_rect = text_input->input->current.features
++ & WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE;
++ struct wlr_surface *focused_surface = text_input->input->focused_surface;
++ struct wlr_box cursor = text_input->input->current.cursor_rectangle;
++
++ struct wlr_output *output;
++ struct wlr_box *output_box;
++ struct wlr_box parent;
++ if (wlr_surface_is_layer_surface(focused_surface)) {
++ struct wlr_layer_surface_v1 *layer_surface =
++ wlr_layer_surface_v1_from_wlr_surface(focused_surface);
++ struct sway_layer_surface *layer =
++ layer_from_wlr_layer_surface_v1(layer_surface);
++ output = layer->layer_surface->output;
++ output_box = wlr_output_layout_get_box(root->output_layout, output);
++ parent = layer->geo;
++ parent.x += output_box->x;
++ parent.y += output_box->y;
++ } else {
++ struct sway_view *view = view_from_wlr_surface(focused_surface);
++ output = wlr_output_layout_output_at(root->output_layout,
++ view->container->surface_x + view->geometry.x,
++ view->container->surface_y + view->geometry.y);
++ output_box = wlr_output_layout_get_box(root->output_layout, output);
++ parent.x = view->container->surface_x + view->geometry.x;
++ parent.y = view->container->surface_y + view->geometry.y;
++ parent.width = view->geometry.width;
++ parent.height = view->geometry.height;
++ }
++
++ if (!cursor_rect) {
++ cursor.x = 0;
++ cursor.y = 0;
++ cursor.width = parent.width;
++ cursor.height = parent.height;
++ }
++
++ int popup_width = popup->popup_surface->surface->current.width;
++ int popup_height = popup->popup_surface->surface->current.height;
++ int x1 = parent.x + cursor.x;
++ int x2 = parent.x + cursor.x + cursor.width;
++ int y1 = parent.y + cursor.y;
++ int y2 = parent.y + cursor.y + cursor.height;
++ int x = x1;
++ int y = y2;
++
++ int available_right = output_box->x + output_box->width - x1;
++ int available_left = x2 - output_box->x;
++ if (available_right < popup_width && available_left > available_right) {
++ x = x2 - popup_width;
++ }
++
++ int available_down = output_box->y + output_box->height - y2;
++ int available_up = y1 - output_box->y;
++ if (available_down < popup_height && available_up > available_down) {
++ y = y1 - popup_height;
++ }
++
++ popup->x = x - parent.x;
++ popup->y = y - parent.y;
++
++ // Hide popup if cursor position is completely out of bounds
++ bool x1_in_bounds = (cursor.x >= 0 && cursor.x < parent.width);
++ bool y1_in_bounds = (cursor.y >= 0 && cursor.y < parent.height);
++ bool x2_in_bounds = (cursor.x + cursor.width >= 0
++ && cursor.x + cursor.width < parent.width);
++ bool y2_in_bounds = (cursor.y + cursor.height >= 0
++ && cursor.y + cursor.height < parent.height);
++ popup->visible =
++ (x1_in_bounds && y1_in_bounds) || (x2_in_bounds && y2_in_bounds);
++
++ if (cursor_rect) {
++ struct wlr_box box = {
++ .x = x1 - x,
++ .y = y1 - y,
++ .width = cursor.width,
++ .height = cursor.height,
++ };
++ wlr_input_popup_surface_v2_send_text_input_rectangle(
++ popup->popup_surface, &box);
++ }
++
++ input_popup_damage(popup);
++}
++
++static void surface_send_enter_iterator(struct wlr_surface *surface,
++ int x, int y, void *data) {
++ struct wlr_output *wlr_output = data;
++ wlr_surface_send_enter(surface, wlr_output);
++}
++
++static void surface_send_leave_iterator(struct wlr_surface *surface,
++ int x, int y, void *data) {
++ struct wlr_output *wlr_output = data;
++ wlr_surface_send_leave(surface, wlr_output);
++}
++
++static void input_popup_send_outputs(struct sway_input_popup *popup,
++ wlr_surface_iterator_func_t iterator) {
++ struct sway_text_input *text_input =
++ relay_get_focused_text_input(popup->relay);
++ if (text_input == NULL || text_input->input->focused_surface == NULL) {
++ return;
++ }
++ struct wlr_surface *focused_surface = text_input->input->focused_surface;
++ if (wlr_surface_is_layer_surface(focused_surface)) {
++ struct wlr_layer_surface_v1 *layer_surface =
++ wlr_layer_surface_v1_from_wlr_surface(focused_surface);
++ struct sway_layer_surface *layer =
++ layer_from_wlr_layer_surface_v1(layer_surface);
++ wlr_surface_for_each_surface(popup->popup_surface->surface,
++ iterator, layer->layer_surface->output);
++ return;
++ }
++ struct sway_view *view = view_from_wlr_surface(focused_surface);
++ for (int i = 0; i < view->container->outputs->length; i++) {
++ struct sway_output *output = view->container->outputs->items[i];
++ wlr_surface_for_each_surface(popup->popup_surface->surface,
++ iterator, output->wlr_output);
++ }
++}
++
++static void handle_im_popup_map(struct wl_listener *listener, void *data) {
++ struct sway_input_popup *popup =
++ wl_container_of(listener, popup, popup_map);
++ input_popup_send_outputs(popup, surface_send_enter_iterator);
++ input_popup_update(popup);
++}
++
++static void handle_im_popup_unmap(struct wl_listener *listener, void *data) {
++ struct sway_input_popup *popup =
++ wl_container_of(listener, popup, popup_unmap);
++ input_popup_send_outputs(popup, surface_send_leave_iterator);
++ input_popup_update(popup);
++}
++
++static void handle_im_popup_destroy(struct wl_listener *listener, void *data) {
++ struct sway_input_popup *popup =
++ wl_container_of(listener, popup, popup_destroy);
++ wl_list_remove(&popup->focused_surface_unmap.link);
++ wl_list_remove(&popup->popup_surface_commit.link);
++ wl_list_remove(&popup->popup_destroy.link);
++ wl_list_remove(&popup->popup_unmap.link);
++ wl_list_remove(&popup->popup_map.link);
++ wl_list_remove(&popup->link);
++ free(popup);
++}
++
++static void handle_im_popup_surface_commit(struct wl_listener *listener,
++ void *data) {
++ struct sway_input_popup *popup =
++ wl_container_of(listener, popup, popup_surface_commit);
++ input_popup_update(popup);
++}
++
++static void handle_im_focused_surface_unmap(
++ struct wl_listener *listener, void *data) {
++ struct sway_input_popup *popup =
++ wl_container_of(listener, popup, focused_surface_unmap);
++ input_popup_update(popup);
++}
++
++static void input_popup_set_focus(struct sway_input_popup *popup,
++ struct wlr_surface *surface) {
++ wl_list_remove(&popup->focused_surface_unmap.link);
++
++ if (surface == NULL) {
++ wl_list_init(&popup->focused_surface_unmap.link);
++ goto update_popup;
++ }
++
++ if (wlr_surface_is_layer_surface(surface)) {
++ struct wlr_layer_surface_v1 *layer_surface =
++ wlr_layer_surface_v1_from_wlr_surface(surface);
++ struct sway_layer_surface *layer =
++ layer_from_wlr_layer_surface_v1(layer_surface);
++ wl_signal_add(
++ &layer->layer_surface->events.unmap, &popup->focused_surface_unmap);
++ goto update_popup;
++ }
++
++ struct sway_view *view = view_from_wlr_surface(surface);
++ wl_signal_add(&view->events.unmap, &popup->focused_surface_unmap);
++
++ // Since the focus has changed, the popup may have to adjust
++update_popup:
++ input_popup_update(popup);
++}
++
++static void handle_im_new_popup_surface(struct wl_listener *listener,
++ void *data) {
++ struct sway_input_method_relay *relay = wl_container_of(listener, relay,
++ input_method_new_popup_surface);
++ struct sway_input_popup *popup = calloc(1, sizeof(*popup));
++ popup->relay = relay;
++ popup->popup_surface = data;
++ popup->popup_surface->data = popup;
++
++ wl_signal_add(&popup->popup_surface->events.map, &popup->popup_map);
++ popup->popup_map.notify = handle_im_popup_map;
++ wl_signal_add(
++ &popup->popup_surface->events.unmap, &popup->popup_unmap);
++ popup->popup_unmap.notify = handle_im_popup_unmap;
++ wl_signal_add(
++ &popup->popup_surface->events.destroy, &popup->popup_destroy);
++ popup->popup_destroy.notify = handle_im_popup_destroy;
++ wl_signal_add(&popup->popup_surface->surface->events.commit,
++ &popup->popup_surface_commit);
++ popup->popup_surface_commit.notify = handle_im_popup_surface_commit;
++ wl_list_init(&popup->focused_surface_unmap.link);
++ popup->focused_surface_unmap.notify = handle_im_focused_surface_unmap;
++
++ struct sway_text_input *text_input = relay_get_focused_text_input(relay);
++ if (text_input != NULL) {
++ input_popup_set_focus(popup, text_input->input->focused_surface);
++ } else {
++ input_popup_set_focus(popup, NULL);
++ }
++
++ wl_list_insert(&relay->input_popups, &popup->link);
++}
++
++bool sway_input_popup_get_position(
++ struct sway_input_popup *popup, int *lx, int *ly) {
++ struct sway_text_input *text_input =
++ relay_get_focused_text_input(popup->relay);
++ if (text_input == NULL || text_input->input->focused_surface == NULL) {
++ *lx = 0;
++ *ly = 0;
++ return false;
++ }
++
++ struct wlr_surface *focused_surface = text_input->input->focused_surface;
++ if (wlr_surface_is_layer_surface(focused_surface)) {
++ struct wlr_layer_surface_v1 *layer_surface =
++ wlr_layer_surface_v1_from_wlr_surface(focused_surface);
++ struct sway_layer_surface *layer =
++ layer_from_wlr_layer_surface_v1(layer_surface);
++ *lx = layer->geo.x + popup->x;
++ *ly = layer->geo.y + popup->y;
++ return true;
++ }
++
++
++ struct sway_view *view = view_from_wlr_surface(
++ text_input->input->focused_surface);
++ if (view->container == NULL) {
++ sway_log(SWAY_INFO, "Tried to find popup, but view is gone");
++ return false;
++ }
++ *lx = view->container->surface_x - view->geometry.x + popup->x;
++ *ly = view->container->surface_y - view->geometry.y + popup->y;
++ return true;
++}
++
++static void text_input_send_enter(struct sway_text_input *text_input,
++ struct wlr_surface *surface) {
++ wlr_text_input_v3_send_enter(text_input->input, surface);
++ struct sway_input_popup *popup;
++ wl_list_for_each(popup, &text_input->relay->input_popups, link) {
++ input_popup_set_focus(popup, surface);
++ }
++}
++
++static void text_input_send_leave(struct sway_text_input *text_input,
++ struct wlr_surface *surface) {
++ wlr_text_input_v3_send_leave(text_input->input);
++ if (text_input->input->focused_surface == surface) {
++ struct sway_input_popup *popup;
++ wl_list_for_each(popup, &text_input->relay->input_popups, link) {
++ input_popup_set_focus(popup, NULL);
++ }
++ }
++}
++
+ static void handle_im_commit(struct wl_listener *listener, void *data) {
+ struct sway_input_method_relay *relay = wl_container_of(listener, relay,
+ input_method_commit);
+@@ -111,7 +439,7 @@ static void handle_im_destroy(struct wl_listener *listener, void *data) {
+ // the input method returns
+ text_input_set_pending_focused_surface(text_input,
+ text_input->input->focused_surface);
+- wlr_text_input_v3_send_leave(text_input->input);
++ text_input_send_leave(text_input, text_input->input->focused_surface);
+ }
+ }
+
+@@ -135,8 +463,13 @@ static void relay_send_im_state(struct sway_input_method_relay *relay,
+ input->current.content_type.hint,
+ input->current.content_type.purpose);
+ }
++ struct sway_input_popup *popup;
++ wl_list_for_each(popup, &relay->input_popups, link) {
++ // send_text_input_rectangle is called in this function
++ input_popup_update(popup);
++ }
+ wlr_input_method_v2_send_done(input_method);
+- // TODO: pass intent, display popup size
++ // TODO: pass intent
+ }
+
+ static void handle_text_input_enable(struct wl_listener *listener, void *data) {
+@@ -276,6 +609,9 @@ static void relay_handle_input_method(struct wl_listener *listener,
+ wl_signal_add(&relay->input_method->events.commit,
+ &relay->input_method_commit);
+ relay->input_method_commit.notify = handle_im_commit;
++ wl_signal_add(&relay->input_method->events.new_popup_surface,
++ &relay->input_method_new_popup_surface);
++ relay->input_method_new_popup_surface.notify = handle_im_new_popup_surface;
+ wl_signal_add(&relay->input_method->events.grab_keyboard,
+ &relay->input_method_grab_keyboard);
+ relay->input_method_grab_keyboard.notify = handle_im_grab_keyboard;
+@@ -285,8 +621,7 @@ static void relay_handle_input_method(struct wl_listener *listener,
+
+ struct sway_text_input *text_input = relay_get_focusable_text_input(relay);
+ if (text_input) {
+- wlr_text_input_v3_send_enter(text_input->input,
+- text_input->pending_focused_surface);
++ text_input_send_enter(text_input, text_input->pending_focused_surface);
+ text_input_set_pending_focused_surface(text_input, NULL);
+ }
+ }
+@@ -295,6 +630,7 @@ void sway_input_method_relay_init(struct sway_seat *seat,
+ struct sway_input_method_relay *relay) {
+ relay->seat = seat;
+ wl_list_init(&relay->text_inputs);
++ wl_list_init(&relay->input_popups);
+
+ relay->text_input_new.notify = relay_handle_text_input;
+ wl_signal_add(&server.text_input->events.text_input,
+@@ -323,8 +659,9 @@ void sway_input_method_relay_set_focus(struct sway_input_method_relay *relay,
+ } else if (text_input->input->focused_surface) {
+ assert(text_input->pending_focused_surface == NULL);
+ if (surface != text_input->input->focused_surface) {
++ text_input_send_leave(
++ text_input, text_input->input->focused_surface);
+ relay_disable_text_input(relay, text_input);
+- wlr_text_input_v3_send_leave(text_input->input);
+ } else {
+ sway_log(SWAY_DEBUG, "IM relay set_focus already focused");
+ continue;
+@@ -335,7 +672,7 @@ void sway_input_method_relay_set_focus(struct sway_input_method_relay *relay,
+ && wl_resource_get_client(text_input->input->resource)
+ == wl_resource_get_client(surface->resource)) {
+ if (relay->input_method) {
+- wlr_text_input_v3_send_enter(text_input->input, surface);
++ text_input_send_enter(text_input, surface);
+ } else {
+ text_input_set_pending_focused_surface(text_input, surface);
+ }
+diff --git a/sway/tree/container.c b/sway/tree/container.c
+index e5149fb622..0b2ad72392 100644
+--- a/sway/tree/container.c
++++ b/sway/tree/container.c
+@@ -396,6 +396,8 @@ static bool surface_is_popup(struct wlr_surface *surface) {
+ wlr_subsurface_from_wlr_surface(surface);
+ surface = subsurface->parent;
+ }
++ if (wlr_surface_is_input_popup_surface_v2(surface))
++ return true;
+ struct wlr_xdg_surface *xdg_surface =
+ wlr_xdg_surface_from_wlr_surface(surface);
+ return xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP;
+diff --git a/sway/tree/view.c b/sway/tree/view.c
+index 1318f5fb37..e0108681fc 100644
+--- a/sway/tree/view.c
++++ b/sway/tree/view.c
+@@ -1188,6 +1188,9 @@ struct sway_view *view_from_wlr_surface(struct wlr_surface *wlr_surface) {
+ if (wlr_surface_is_layer_surface(wlr_surface)) {
+ return NULL;
+ }
++ if (wlr_surface_is_input_popup_surface_v2(wlr_surface)) {
++ return NULL;
++ }
+
+ const char *role = wlr_surface->role ? wlr_surface->role->name : NULL;
+ sway_log(SWAY_DEBUG, "Surface of unknown type (role %s): %p",
diff --git a/0002-im-Handle-text-disable-on-focus-lost-properly.patch b/0002-im-Handle-text-disable-on-focus-lost-properly.patch
deleted file mode 100644
index 77b7256bb00d..000000000000
--- a/0002-im-Handle-text-disable-on-focus-lost-properly.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From ec36e11373156f1475e5e7cb59d3a7ce5cdc76d5 Mon Sep 17 00:00:00 2001
-From: Hyeon Kim <simnalamburt@gmail.com>
-Date: Thu, 28 Jan 2021 18:44:37 +0900
-Subject: [PATCH 2/2] im: Handle text disable on focus lost properly
-
-Reference:
- https://github.com/swaywm/sway/pull/4932#issuecomment-767062561
----
- sway/input/text_input.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/sway/input/text_input.c b/sway/input/text_input.c
-index 8a29f186..1c7e21cc 100644
---- a/sway/input/text_input.c
-+++ b/sway/input/text_input.c
-@@ -167,6 +167,10 @@ static void relay_disable_text_input(struct sway_input_method_relay *relay,
- sway_log(SWAY_DEBUG, "Disabling text input, but input method is gone");
- return;
- }
-+ if (text_input->input->focused_surface == NULL) {
-+ sway_log(SWAY_DEBUG, "Disabling text input, but no longer focused");
-+ return;
-+ }
- wlr_input_method_v2_send_deactivate(relay->input_method);
- relay_send_im_state(relay, text_input->input);
- }
---
-2.30.0
-
diff --git a/50-systemd-user.conf b/50-systemd-user.conf
index 72e5dcd98b02..d75ccdb2adbd 100644
--- a/50-systemd-user.conf
+++ b/50-systemd-user.conf
@@ -2,6 +2,6 @@
# See FS#63021
# Adapted from xorg's 50-systemd-user.sh, which achieves a similar goal.
-exec systemctl --user import-environment DISPLAY WAYLAND_DISPLAY SWAYSOCK
+exec systemctl --user import-environment DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP
exec hash dbus-update-activation-environment 2>/dev/null && \
- dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK
+ dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP
diff --git a/PKGBUILD b/PKGBUILD
index 4398f0bf2035..7a8e86fd3392 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -2,14 +2,13 @@
# Contributor: Brett Cornwall <ainola@archlinux.org>
# Contributor: Maxim Baz <$pkgname at maximbaz dot com>
# Contributor: Alexander F. Rødseth <xyproto@archlinux.org>
+# Contributor: tinywrkb <tinywrkb@gmail.com>
pkgname=sway-im
-_pkgname=sway
-pkgver=1.5.1.r2.ec36e113
-_pkgver=1.5.1
+pkgver=1.7
epoch=1
pkgrel=1
-pkgdesc='sway Wayland compositor with input method keyboard grab support'
+pkgdesc='Tiling Wayland compositor and replacement for the i3 window manager, with input method popups v2 support'
arch=(x86_64)
url='https://swaywm.org/'
license=(MIT)
@@ -27,7 +26,6 @@ depends=(
makedepends=(git meson ninja scdoc setconf wayland-protocols)
backup=(etc/sway/config)
optdepends=(
- 'alacritty: Terminal emulator used by the default config'
'dmenu: Application launcher'
'grim: Screenshot utility'
'i3status: Status line'
@@ -39,45 +37,43 @@ optdepends=(
'waybar: Highly customizable bar'
'xorg-xwayland: X11 support'
)
-source=("https://github.com/swaywm/sway/releases/download/$_pkgver/sway-$_pkgver.tar.gz"
- "https://github.com/swaywm/sway/releases/download/$_pkgver/sway-$_pkgver.tar.gz.sig"
- "0001-Implement-input-method-keyboard-grab.patch"
- "0002-im-Handle-text-disable-on-focus-lost-properly.patch"
- "50-systemd-user.conf")
-sha512sums=('3b937249db2875100bc22e99f955a3300d3294a296fb37006fa1468a3986bf4fa8e5197279e3587bd8dc29f31adff8fbdc9ddc840e7be982b73331a05cd06ba5'
+source=("https://github.com/swaywm/sway/releases/download/$pkgver/sway-$pkgver.tar.gz"
+ "https://github.com/swaywm/sway/releases/download/$pkgver/sway-$pkgver.tar.gz.sig"
+ "50-systemd-user.conf"
+ "0001-text_input-Implement-input-method-popups.patch")
+sha512sums=('028cf5d504d5914bfb78d44156d6a290de660c5ed0638f4e2c56e5be76db9b0baeda035e1fa1ae23559016bd7e4312f7ff70c2fb4904df25358577c1a3d21243'
'SKIP'
- 'd1cad32660f7a39cac423808f96c3253355a657ffc466617a68e574d02b2d47016bdeb32a3a496a95fe5a75fb132903f4b551b55eae7641cc881be68be2e52e9'
- '3bbdef63985980ce52caf51aa141cdd619fb055c2ba199e783666da779e4ae38c4338ddad37ba29ea8a0c11b0c692834c1c4a00d5260c4dc09c041b5d6bc6253'
- '57590bc0d14c87289a4a9cd67991c6a841e54244d2a6186b5da5a08e633de2e8631959fa8c77ede211b0a5f315d920f2c1350951a53d6f2e9e81859056cb3c9e')
+ 'c2b7d808f4231f318e03789015624fd4cf32b81434b15406570b4e144c0defc54e216d881447e6fd9fc18d7da608cccb61c32e0e1fab2f1fe2750acf812d3137'
+ 'b39325808c7327c47d3f024d355392387b65240f86d5391eafd9b52c70d89cb50192a58f3bac954abc90430806b73799a664c558e12fcdcf23529b77752c14cd')
validpgpkeys=('34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48' # Simon Ser
'9DDA3B9FA5D58DD5392C78E652CB6609B22DA89A') # Drew DeVault
-provides=('sway')
conflicts=('sway')
+provides=('sway')
prepare() {
- cd "$_pkgname-$_pkgver"
-
- patch -p1 <"$srcdir"/0001-Implement-input-method-keyboard-grab.patch
- patch -p1 <"$srcdir"/0002-im-Handle-text-disable-on-focus-lost-properly.patch
+ cd "sway-$pkgver"
# Set the version information to 'Arch Linux' instead of 'makepkg'
sed -i "s/branch \\\'@1@\\\'/Arch Linux/g" meson.build
+
+ # https://github.com/swaywm/sway/pull/5890
+ patch -Np1 -i ../0001-text_input-Implement-input-method-popups.patch
}
build() {
mkdir -p build
- arch-meson build "$_pkgname-$_pkgver" -D werror=false -D b_ndebug=true
+ arch-meson build "sway-$pkgver" -D sd-bus-provider=libsystemd -D werror=false -D b_ndebug=true
ninja -C build
}
package() {
DESTDIR="$pkgdir" ninja -C build install
- install -Dm644 "$_pkgname-$_pkgver/LICENSE" "$pkgdir/usr/share/licenses/$_pkgname/LICENSE"
+ install -Dm644 "sway-$pkgver/LICENSE" "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
install -Dm644 50-systemd-user.conf -t "$pkgdir/etc/sway/config.d/"
for util in autoname-workspaces.py inactive-windows-transparency.py grimshot; do
- install -Dm755 "$_pkgname-$_pkgver/contrib/$util" -t \
- "$pkgdir/usr/share/$_pkgname/scripts"
+ install -Dm755 "sway-$pkgver/contrib/$util" -t \
+ "$pkgdir/usr/share/sway/scripts"
done
}