aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/seat.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r--sway/input/seat.c225
1 files changed, 179 insertions, 46 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 1f5865ee..b21e1b86 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -11,6 +11,7 @@
11#include <wlr/types/wlr_output_layout.h> 11#include <wlr/types/wlr_output_layout.h>
12#include <wlr/types/wlr_primary_selection.h> 12#include <wlr/types/wlr_primary_selection.h>
13#include <wlr/types/wlr_tablet_v2.h> 13#include <wlr/types/wlr_tablet_v2.h>
14#include <wlr/types/wlr_touch.h>
14#include <wlr/types/wlr_xcursor_manager.h> 15#include <wlr/types/wlr_xcursor_manager.h>
15#include "config.h" 16#include "config.h"
16#include "list.h" 17#include "list.h"
@@ -20,6 +21,7 @@
20#include "sway/input/cursor.h" 21#include "sway/input/cursor.h"
21#include "sway/input/input-manager.h" 22#include "sway/input/input-manager.h"
22#include "sway/input/keyboard.h" 23#include "sway/input/keyboard.h"
24#include "sway/input/libinput.h"
23#include "sway/input/seat.h" 25#include "sway/input/seat.h"
24#include "sway/input/switch.h" 26#include "sway/input/switch.h"
25#include "sway/input/tablet.h" 27#include "sway/input/tablet.h"
@@ -41,6 +43,7 @@ static void seat_device_destroy(struct sway_seat_device *seat_device) {
41 sway_keyboard_destroy(seat_device->keyboard); 43 sway_keyboard_destroy(seat_device->keyboard);
42 sway_tablet_destroy(seat_device->tablet); 44 sway_tablet_destroy(seat_device->tablet);
43 sway_tablet_pad_destroy(seat_device->tablet_pad); 45 sway_tablet_pad_destroy(seat_device->tablet_pad);
46 sway_switch_destroy(seat_device->switch_device);
44 wlr_cursor_detach_input_device(seat_device->sway_seat->cursor->cursor, 47 wlr_cursor_detach_input_device(seat_device->sway_seat->cursor->cursor,
45 seat_device->input_device->wlr_device); 48 seat_device->input_device->wlr_device);
46 wl_list_remove(&seat_device->link); 49 wl_list_remove(&seat_device->link);
@@ -50,6 +53,16 @@ static void seat_device_destroy(struct sway_seat_device *seat_device) {
50static void seat_node_destroy(struct sway_seat_node *seat_node) { 53static void seat_node_destroy(struct sway_seat_node *seat_node) {
51 wl_list_remove(&seat_node->destroy.link); 54 wl_list_remove(&seat_node->destroy.link);
52 wl_list_remove(&seat_node->link); 55 wl_list_remove(&seat_node->link);
56
57 /*
58 * This is the only time we remove items from the focus stack without
59 * immediately re-adding them. If we just removed the last thing,
60 * mark that nothing has focus anymore.
61 */
62 if (wl_list_empty(&seat_node->seat->focus_stack)) {
63 seat_node->seat->has_focus = false;
64 }
65
53 free(seat_node); 66 free(seat_node);
54} 67}
55 68
@@ -129,7 +142,7 @@ static struct sway_keyboard *sway_keyboard_for_wlr_keyboard(
129 if (input_device->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { 142 if (input_device->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) {
130 continue; 143 continue;
131 } 144 }
132 if (input_device->wlr_device->keyboard == wlr_keyboard) { 145 if (input_device->wlr_device == &wlr_keyboard->base) {
133 return seat_device->keyboard; 146 return seat_device->keyboard;
134 } 147 }
135 } 148 }
@@ -137,7 +150,7 @@ static struct sway_keyboard *sway_keyboard_for_wlr_keyboard(
137 wl_list_for_each(group, &seat->keyboard_groups, link) { 150 wl_list_for_each(group, &seat->keyboard_groups, link) {
138 struct sway_input_device *input_device = 151 struct sway_input_device *input_device =
139 group->seat_device->input_device; 152 group->seat_device->input_device;
140 if (input_device->wlr_device->keyboard == wlr_keyboard) { 153 if (input_device->wlr_device == &wlr_keyboard->base) {
141 return group->seat_device->keyboard; 154 return group->seat_device->keyboard;
142 } 155 }
143 } 156 }
@@ -199,6 +212,15 @@ static void seat_send_focus(struct sway_node *node, struct sway_seat *seat) {
199 } 212 }
200} 213}
201 214
215void sway_force_focus(struct wlr_surface *surface) {
216 struct sway_seat *seat;
217 wl_list_for_each(seat, &server.input->seats, link) {
218 seat_keyboard_notify_enter(seat, surface);
219 seat_tablet_pads_notify_enter(seat, surface);
220 sway_input_method_relay_set_focus(&seat->im_relay, surface);
221 }
222}
223
202void seat_for_each_node(struct sway_seat *seat, 224void seat_for_each_node(struct sway_seat *seat,
203 void (*f)(struct sway_node *node, void *data), void *data) { 225 void (*f)(struct sway_node *node, void *data), void *data) {
204 struct sway_seat_node *current = NULL; 226 struct sway_seat_node *current = NULL;
@@ -209,14 +231,13 @@ void seat_for_each_node(struct sway_seat *seat,
209 231
210struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, 232struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat,
211 struct sway_node *ancestor) { 233 struct sway_node *ancestor) {
212 if (ancestor->type == N_CONTAINER && ancestor->sway_container->view) { 234 if (node_is_view(ancestor)) {
213 return ancestor->sway_container; 235 return ancestor->sway_container;
214 } 236 }
215 struct sway_seat_node *current; 237 struct sway_seat_node *current;
216 wl_list_for_each(current, &seat->focus_stack, link) { 238 wl_list_for_each(current, &seat->focus_stack, link) {
217 struct sway_node *node = current->node; 239 struct sway_node *node = current->node;
218 if (node->type == N_CONTAINER && node->sway_container->view && 240 if (node_is_view(node) && node_has_ancestor(node, ancestor)) {
219 node_has_ancestor(node, ancestor)) {
220 return node->sway_container; 241 return node->sway_container;
221 } 242 }
222 } 243 }
@@ -235,7 +256,7 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) {
235 seat_node_destroy(seat_node); 256 seat_node_destroy(seat_node);
236 // If an unmanaged or layer surface is focused when an output gets 257 // If an unmanaged or layer surface is focused when an output gets
237 // disabled and an empty workspace on the output was focused by the 258 // disabled and an empty workspace on the output was focused by the
238 // seat, the seat needs to refocus it's focus inactive to update the 259 // seat, the seat needs to refocus its focus inactive to update the
239 // value of seat->workspace. 260 // value of seat->workspace.
240 if (seat->workspace == node->sway_workspace) { 261 if (seat->workspace == node->sway_workspace) {
241 struct sway_node *node = seat_get_focus_inactive(seat, &root->node); 262 struct sway_node *node = seat_get_focus_inactive(seat, &root->node);
@@ -309,8 +330,8 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) {
309 // Setting focus_inactive 330 // Setting focus_inactive
310 focus = seat_get_focus_inactive(seat, &root->node); 331 focus = seat_get_focus_inactive(seat, &root->node);
311 seat_set_raw_focus(seat, next_focus); 332 seat_set_raw_focus(seat, next_focus);
312 if (focus->type == N_CONTAINER && focus->sway_container->workspace) { 333 if (focus->type == N_CONTAINER && focus->sway_container->pending.workspace) {
313 seat_set_raw_focus(seat, &focus->sway_container->workspace->node); 334 seat_set_raw_focus(seat, &focus->sway_container->pending.workspace->node);
314 } 335 }
315 seat_set_raw_focus(seat, focus); 336 seat_set_raw_focus(seat, focus);
316 } 337 }
@@ -368,8 +389,8 @@ void drag_icon_update_position(struct sway_drag_icon *icon) {
368 case WLR_DRAG_GRAB_KEYBOARD: 389 case WLR_DRAG_GRAB_KEYBOARD:
369 return; 390 return;
370 case WLR_DRAG_GRAB_KEYBOARD_POINTER: 391 case WLR_DRAG_GRAB_KEYBOARD_POINTER:
371 icon->x = cursor->x; 392 icon->x = cursor->x + wlr_icon->surface->sx;
372 icon->y = cursor->y; 393 icon->y = cursor->y + wlr_icon->surface->sy;
373 break; 394 break;
374 case WLR_DRAG_GRAB_KEYBOARD_TOUCH:; 395 case WLR_DRAG_GRAB_KEYBOARD_TOUCH:;
375 struct wlr_touch_point *point = 396 struct wlr_touch_point *point =
@@ -377,8 +398,8 @@ void drag_icon_update_position(struct sway_drag_icon *icon) {
377 if (point == NULL) { 398 if (point == NULL) {
378 return; 399 return;
379 } 400 }
380 icon->x = seat->touch_x; 401 icon->x = seat->touch_x + wlr_icon->surface->sx;
381 icon->y = seat->touch_y; 402 icon->y = seat->touch_y + wlr_icon->surface->sy;
382 } 403 }
383 404
384 drag_icon_damage_whole(icon); 405 drag_icon_damage_whole(icon);
@@ -666,6 +687,40 @@ static void seat_reset_input_config(struct sway_seat *seat,
666 sway_device->input_device->wlr_device, NULL); 687 sway_device->input_device->wlr_device, NULL);
667} 688}
668 689
690static bool has_prefix(const char *str, const char *prefix) {
691 return strncmp(str, prefix, strlen(prefix)) == 0;
692}
693
694/**
695 * Get the name of the built-in output, if any. Returns NULL if there isn't
696 * exactly one built-in output.
697 */
698static const char *get_builtin_output_name(void) {
699 const char *match = NULL;
700 for (int i = 0; i < root->outputs->length; ++i) {
701 struct sway_output *output = root->outputs->items[i];
702 const char *name = output->wlr_output->name;
703 if (has_prefix(name, "eDP-") || has_prefix(name, "LVDS-") ||
704 has_prefix(name, "DSI-")) {
705 if (match != NULL) {
706 return NULL;
707 }
708 match = name;
709 }
710 }
711 return match;
712}
713
714static bool is_touch_or_tablet_tool(struct sway_seat_device *seat_device) {
715 switch (seat_device->input_device->wlr_device->type) {
716 case WLR_INPUT_DEVICE_TOUCH:
717 case WLR_INPUT_DEVICE_TABLET_TOOL:
718 return true;
719 default:
720 return false;
721 }
722}
723
669static void seat_apply_input_config(struct sway_seat *seat, 724static void seat_apply_input_config(struct sway_seat *seat,
670 struct sway_seat_device *sway_device) { 725 struct sway_seat_device *sway_device) {
671 struct input_config *ic = 726 struct input_config *ic =
@@ -680,8 +735,33 @@ static void seat_apply_input_config(struct sway_seat *seat,
680 ic == NULL ? MAPPED_TO_DEFAULT : ic->mapped_to; 735 ic == NULL ? MAPPED_TO_DEFAULT : ic->mapped_to;
681 736
682 switch (mapped_to) { 737 switch (mapped_to) {
683 case MAPPED_TO_DEFAULT: 738 case MAPPED_TO_DEFAULT:;
684 mapped_to_output = sway_device->input_device->wlr_device->output_name; 739 /*
740 * If the wlroots backend provides an output name, use that.
741 *
742 * Otherwise, try to map built-in touch and pointer devices to the
743 * built-in output.
744 */
745 struct wlr_input_device *dev = sway_device->input_device->wlr_device;
746 switch (dev->type) {
747 case WLR_INPUT_DEVICE_POINTER:
748 mapped_to_output = wlr_pointer_from_input_device(dev)->output_name;
749 break;
750 case WLR_INPUT_DEVICE_TOUCH:
751 mapped_to_output = wlr_touch_from_input_device(dev)->output_name;
752 break;
753 default:
754 mapped_to_output = NULL;
755 break;
756 }
757 if (mapped_to_output == NULL && is_touch_or_tablet_tool(sway_device) &&
758 sway_libinput_device_is_builtin(sway_device->input_device)) {
759 mapped_to_output = get_builtin_output_name();
760 if (mapped_to_output) {
761 sway_log(SWAY_DEBUG, "Auto-detected output '%s' for device '%s'",
762 mapped_to_output, sway_device->input_device->identifier);
763 }
764 }
685 if (mapped_to_output == NULL) { 765 if (mapped_to_output == NULL) {
686 return; 766 return;
687 } 767 }
@@ -742,12 +822,14 @@ static void seat_configure_keyboard(struct sway_seat *seat,
742 } 822 }
743 sway_keyboard_configure(seat_device->keyboard); 823 sway_keyboard_configure(seat_device->keyboard);
744 wlr_seat_set_keyboard(seat->wlr_seat, 824 wlr_seat_set_keyboard(seat->wlr_seat,
745 seat_device->input_device->wlr_device); 825 wlr_keyboard_from_input_device(seat_device->input_device->wlr_device));
746 struct sway_node *focus = seat_get_focus(seat); 826
747 if (focus && node_is_view(focus)) { 827 // force notify reenter to pick up the new configuration. This reuses
748 // force notify reenter to pick up the new configuration 828 // the current focused surface to avoid breaking input grabs.
829 struct wlr_surface *surface = seat->wlr_seat->keyboard_state.focused_surface;
830 if (surface) {
749 wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat); 831 wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat);
750 seat_keyboard_notify_enter(seat, focus->sway_container->view->surface); 832 seat_keyboard_notify_enter(seat, surface);
751 } 833 }
752} 834}
753 835
@@ -999,7 +1081,8 @@ void seat_configure_xcursor(struct sway_seat *seat) {
999bool seat_is_input_allowed(struct sway_seat *seat, 1081bool seat_is_input_allowed(struct sway_seat *seat,
1000 struct wlr_surface *surface) { 1082 struct wlr_surface *surface) {
1001 struct wl_client *client = wl_resource_get_client(surface->resource); 1083 struct wl_client *client = wl_resource_get_client(surface->resource);
1002 return !seat->exclusive_client || seat->exclusive_client == client; 1084 return seat->exclusive_client == client ||
1085 (seat->exclusive_client == NULL && !server.session_lock.locked);
1003} 1086}
1004 1087
1005static void send_unfocus(struct sway_container *con, void *data) { 1088static void send_unfocus(struct sway_container *con, void *data) {
@@ -1086,29 +1169,23 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
1086 } 1169 }
1087 1170
1088 struct sway_workspace *new_workspace = node->type == N_WORKSPACE ? 1171 struct sway_workspace *new_workspace = node->type == N_WORKSPACE ?
1089 node->sway_workspace : node->sway_container->workspace; 1172 node->sway_workspace : node->sway_container->pending.workspace;
1090 struct sway_container *container = node->type == N_CONTAINER ? 1173 struct sway_container *container = node->type == N_CONTAINER ?
1091 node->sway_container : NULL; 1174 node->sway_container : NULL;
1092 1175
1093 // Deny setting focus to a view which is hidden by a fullscreen container 1176 // Deny setting focus to a view which is hidden by a fullscreen container or global
1094 if (new_workspace && new_workspace->fullscreen && container && 1177 if (container && container_obstructing_fullscreen_container(container)) {
1095 !container_is_fullscreen_or_child(container)) { 1178 return;
1096 // Unless it's a transient container
1097 if (!container_is_transient_for(container, new_workspace->fullscreen)) {
1098 return;
1099 }
1100 } 1179 }
1180
1101 // Deny setting focus to a workspace node when using fullscreen global 1181 // Deny setting focus to a workspace node when using fullscreen global
1102 if (root->fullscreen_global && !container && new_workspace) { 1182 if (root->fullscreen_global && !container && new_workspace) {
1103 return; 1183 return;
1104 } 1184 }
1105 // Deny setting focus to a view which is hidden by a fullscreen global 1185
1106 if (root->fullscreen_global && container != root->fullscreen_global && 1186 // Deny setting focus when an input grab or lockscreen is active
1107 !container_has_ancestor(container, root->fullscreen_global)) { 1187 if (container && container->view && !seat_is_input_allowed(seat, container->view->surface)) {
1108 // Unless it's a transient container 1188 return;
1109 if (!container_is_transient_for(container, root->fullscreen_global)) {
1110 return;
1111 }
1112 } 1189 }
1113 1190
1114 struct sway_output *new_output = 1191 struct sway_output *new_output =
@@ -1135,10 +1212,10 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
1135 // Put the container parents on the focus stack, then the workspace, then 1212 // Put the container parents on the focus stack, then the workspace, then
1136 // the focused container. 1213 // the focused container.
1137 if (container) { 1214 if (container) {
1138 struct sway_container *parent = container->parent; 1215 struct sway_container *parent = container->pending.parent;
1139 while (parent) { 1216 while (parent) {
1140 seat_set_raw_focus(seat, &parent->node); 1217 seat_set_raw_focus(seat, &parent->node);
1141 parent = parent->parent; 1218 parent = parent->pending.parent;
1142 } 1219 }
1143 } 1220 }
1144 if (new_workspace) { 1221 if (new_workspace) {
@@ -1234,6 +1311,7 @@ void seat_set_focus_surface(struct sway_seat *seat,
1234 wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat); 1311 wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat);
1235 } 1312 }
1236 1313
1314 sway_input_method_relay_set_focus(&seat->im_relay, surface);
1237 seat_tablet_pads_notify_enter(seat, surface); 1315 seat_tablet_pads_notify_enter(seat, surface);
1238} 1316}
1239 1317
@@ -1326,7 +1404,7 @@ struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat,
1326 struct sway_node *node = current->node; 1404 struct sway_node *node = current->node;
1327 if (node->type == N_CONTAINER && 1405 if (node->type == N_CONTAINER &&
1328 !container_is_floating_or_child(node->sway_container) && 1406 !container_is_floating_or_child(node->sway_container) &&
1329 node->sway_container->workspace == workspace) { 1407 node->sway_container->pending.workspace == workspace) {
1330 return node->sway_container; 1408 return node->sway_container;
1331 } 1409 }
1332 } 1410 }
@@ -1343,7 +1421,7 @@ struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat,
1343 struct sway_node *node = current->node; 1421 struct sway_node *node = current->node;
1344 if (node->type == N_CONTAINER && 1422 if (node->type == N_CONTAINER &&
1345 container_is_floating_or_child(node->sway_container) && 1423 container_is_floating_or_child(node->sway_container) &&
1346 node->sway_container->workspace == workspace) { 1424 node->sway_container->pending.workspace == workspace) {
1347 return node->sway_container; 1425 return node->sway_container;
1348 } 1426 }
1349 } 1427 }
@@ -1377,9 +1455,8 @@ struct sway_node *seat_get_focus(struct sway_seat *seat) {
1377 if (!seat->has_focus) { 1455 if (!seat->has_focus) {
1378 return NULL; 1456 return NULL;
1379 } 1457 }
1380 if (wl_list_empty(&seat->focus_stack)) { 1458 sway_assert(!wl_list_empty(&seat->focus_stack),
1381 return NULL; 1459 "focus_stack is empty, but has_focus is true");
1382 }
1383 struct sway_seat_node *current = 1460 struct sway_seat_node *current =
1384 wl_container_of(seat->focus_stack.next, current, link); 1461 wl_container_of(seat->focus_stack.next, current, link);
1385 return current->node; 1462 return current->node;
@@ -1391,7 +1468,7 @@ struct sway_workspace *seat_get_focused_workspace(struct sway_seat *seat) {
1391 return NULL; 1468 return NULL;
1392 } 1469 }
1393 if (focus->type == N_CONTAINER) { 1470 if (focus->type == N_CONTAINER) {
1394 return focus->sway_container->workspace; 1471 return focus->sway_container->pending.workspace;
1395 } 1472 }
1396 if (focus->type == N_WORKSPACE) { 1473 if (focus->type == N_WORKSPACE) {
1397 return focus->sway_workspace; 1474 return focus->sway_workspace;
@@ -1404,8 +1481,8 @@ struct sway_workspace *seat_get_last_known_workspace(struct sway_seat *seat) {
1404 wl_list_for_each(current, &seat->focus_stack, link) { 1481 wl_list_for_each(current, &seat->focus_stack, link) {
1405 struct sway_node *node = current->node; 1482 struct sway_node *node = current->node;
1406 if (node->type == N_CONTAINER && 1483 if (node->type == N_CONTAINER &&
1407 node->sway_container->workspace) { 1484 node->sway_container->pending.workspace) {
1408 return node->sway_container->workspace; 1485 return node->sway_container->pending.workspace;
1409 } else if (node->type == N_WORKSPACE) { 1486 } else if (node->type == N_WORKSPACE) {
1410 return node->sway_workspace; 1487 return node->sway_workspace;
1411 } 1488 }
@@ -1514,7 +1591,7 @@ void seatop_pointer_motion(struct sway_seat *seat, uint32_t time_msec) {
1514} 1591}
1515 1592
1516void seatop_pointer_axis(struct sway_seat *seat, 1593void seatop_pointer_axis(struct sway_seat *seat,
1517 struct wlr_event_pointer_axis *event) { 1594 struct wlr_pointer_axis_event *event) {
1518 if (seat->seatop_impl->pointer_axis) { 1595 if (seat->seatop_impl->pointer_axis) {
1519 seat->seatop_impl->pointer_axis(seat, event); 1596 seat->seatop_impl->pointer_axis(seat, event);
1520 } 1597 }
@@ -1537,6 +1614,62 @@ void seatop_tablet_tool_motion(struct sway_seat *seat,
1537 } 1614 }
1538} 1615}
1539 1616
1617void seatop_hold_begin(struct sway_seat *seat,
1618 struct wlr_pointer_hold_begin_event *event) {
1619 if (seat->seatop_impl->hold_begin) {
1620 seat->seatop_impl->hold_begin(seat, event);
1621 }
1622}
1623
1624void seatop_hold_end(struct sway_seat *seat,
1625 struct wlr_pointer_hold_end_event *event) {
1626 if (seat->seatop_impl->hold_end) {
1627 seat->seatop_impl->hold_end(seat, event);
1628 }
1629}
1630
1631void seatop_pinch_begin(struct sway_seat *seat,
1632 struct wlr_pointer_pinch_begin_event *event) {
1633 if (seat->seatop_impl->pinch_begin) {
1634 seat->seatop_impl->pinch_begin(seat, event);
1635 }
1636}
1637
1638void seatop_pinch_update(struct sway_seat *seat,
1639 struct wlr_pointer_pinch_update_event *event) {
1640 if (seat->seatop_impl->pinch_update) {
1641 seat->seatop_impl->pinch_update(seat, event);
1642 }
1643}
1644
1645void seatop_pinch_end(struct sway_seat *seat,
1646 struct wlr_pointer_pinch_end_event *event) {
1647 if (seat->seatop_impl->pinch_end) {
1648 seat->seatop_impl->pinch_end(seat, event);
1649 }
1650}
1651
1652void seatop_swipe_begin(struct sway_seat *seat,
1653 struct wlr_pointer_swipe_begin_event *event) {
1654 if (seat->seatop_impl->swipe_begin) {
1655 seat->seatop_impl->swipe_begin(seat, event);
1656 }
1657}
1658
1659void seatop_swipe_update(struct sway_seat *seat,
1660 struct wlr_pointer_swipe_update_event *event) {
1661 if (seat->seatop_impl->swipe_update) {
1662 seat->seatop_impl->swipe_update(seat, event);
1663 }
1664}
1665
1666void seatop_swipe_end(struct sway_seat *seat,
1667 struct wlr_pointer_swipe_end_event *event) {
1668 if (seat->seatop_impl->swipe_end) {
1669 seat->seatop_impl->swipe_end(seat, event);
1670 }
1671}
1672
1540void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) { 1673void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) {
1541 if (seat->seatop_impl->rebase) { 1674 if (seat->seatop_impl->rebase) {
1542 seat->seatop_impl->rebase(seat, time_msec); 1675 seat->seatop_impl->rebase(seat, time_msec);