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.c89
1 files changed, 64 insertions, 25 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 1f5865ee..2d714acd 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -20,6 +20,7 @@
20#include "sway/input/cursor.h" 20#include "sway/input/cursor.h"
21#include "sway/input/input-manager.h" 21#include "sway/input/input-manager.h"
22#include "sway/input/keyboard.h" 22#include "sway/input/keyboard.h"
23#include "sway/input/libinput.h"
23#include "sway/input/seat.h" 24#include "sway/input/seat.h"
24#include "sway/input/switch.h" 25#include "sway/input/switch.h"
25#include "sway/input/tablet.h" 26#include "sway/input/tablet.h"
@@ -309,8 +310,8 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) {
309 // Setting focus_inactive 310 // Setting focus_inactive
310 focus = seat_get_focus_inactive(seat, &root->node); 311 focus = seat_get_focus_inactive(seat, &root->node);
311 seat_set_raw_focus(seat, next_focus); 312 seat_set_raw_focus(seat, next_focus);
312 if (focus->type == N_CONTAINER && focus->sway_container->workspace) { 313 if (focus->type == N_CONTAINER && focus->sway_container->pending.workspace) {
313 seat_set_raw_focus(seat, &focus->sway_container->workspace->node); 314 seat_set_raw_focus(seat, &focus->sway_container->pending.workspace->node);
314 } 315 }
315 seat_set_raw_focus(seat, focus); 316 seat_set_raw_focus(seat, focus);
316 } 317 }
@@ -666,6 +667,40 @@ static void seat_reset_input_config(struct sway_seat *seat,
666 sway_device->input_device->wlr_device, NULL); 667 sway_device->input_device->wlr_device, NULL);
667} 668}
668 669
670static bool has_prefix(const char *str, const char *prefix) {
671 return strncmp(str, prefix, strlen(prefix)) == 0;
672}
673
674/**
675 * Get the name of the built-in output, if any. Returns NULL if there isn't
676 * exactly one built-in output.
677 */
678static const char *get_builtin_output_name(void) {
679 const char *match = NULL;
680 for (int i = 0; i < root->outputs->length; ++i) {
681 struct sway_output *output = root->outputs->items[i];
682 const char *name = output->wlr_output->name;
683 if (has_prefix(name, "eDP-") || has_prefix(name, "LVDS-") ||
684 has_prefix(name, "DSI-")) {
685 if (match != NULL) {
686 return NULL;
687 }
688 match = name;
689 }
690 }
691 return match;
692}
693
694static bool is_touch_or_tablet_tool(struct sway_seat_device *seat_device) {
695 switch (seat_device->input_device->wlr_device->type) {
696 case WLR_INPUT_DEVICE_TOUCH:
697 case WLR_INPUT_DEVICE_TABLET_TOOL:
698 return true;
699 default:
700 return false;
701 }
702}
703
669static void seat_apply_input_config(struct sway_seat *seat, 704static void seat_apply_input_config(struct sway_seat *seat,
670 struct sway_seat_device *sway_device) { 705 struct sway_seat_device *sway_device) {
671 struct input_config *ic = 706 struct input_config *ic =
@@ -681,7 +716,21 @@ static void seat_apply_input_config(struct sway_seat *seat,
681 716
682 switch (mapped_to) { 717 switch (mapped_to) {
683 case MAPPED_TO_DEFAULT: 718 case MAPPED_TO_DEFAULT:
719 /*
720 * If the wlroots backend provides an output name, use that.
721 *
722 * Otherwise, try to map built-in touch and tablet tool devices to the
723 * built-in output.
724 */
684 mapped_to_output = sway_device->input_device->wlr_device->output_name; 725 mapped_to_output = sway_device->input_device->wlr_device->output_name;
726 if (mapped_to_output == NULL && is_touch_or_tablet_tool(sway_device) &&
727 sway_libinput_device_is_builtin(sway_device->input_device)) {
728 mapped_to_output = get_builtin_output_name();
729 if (mapped_to_output) {
730 sway_log(SWAY_DEBUG, "Auto-detected output '%s' for device '%s'",
731 mapped_to_output, sway_device->input_device->identifier);
732 }
733 }
685 if (mapped_to_output == NULL) { 734 if (mapped_to_output == NULL) {
686 return; 735 return;
687 } 736 }
@@ -1086,30 +1135,19 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
1086 } 1135 }
1087 1136
1088 struct sway_workspace *new_workspace = node->type == N_WORKSPACE ? 1137 struct sway_workspace *new_workspace = node->type == N_WORKSPACE ?
1089 node->sway_workspace : node->sway_container->workspace; 1138 node->sway_workspace : node->sway_container->pending.workspace;
1090 struct sway_container *container = node->type == N_CONTAINER ? 1139 struct sway_container *container = node->type == N_CONTAINER ?
1091 node->sway_container : NULL; 1140 node->sway_container : NULL;
1092 1141
1093 // Deny setting focus to a view which is hidden by a fullscreen container 1142 // Deny setting focus to a view which is hidden by a fullscreen container or global
1094 if (new_workspace && new_workspace->fullscreen && container && 1143 if (container && container_obstructing_fullscreen_container(container)) {
1095 !container_is_fullscreen_or_child(container)) { 1144 return;
1096 // Unless it's a transient container
1097 if (!container_is_transient_for(container, new_workspace->fullscreen)) {
1098 return;
1099 }
1100 } 1145 }
1146
1101 // Deny setting focus to a workspace node when using fullscreen global 1147 // Deny setting focus to a workspace node when using fullscreen global
1102 if (root->fullscreen_global && !container && new_workspace) { 1148 if (root->fullscreen_global && !container && new_workspace) {
1103 return; 1149 return;
1104 } 1150 }
1105 // Deny setting focus to a view which is hidden by a fullscreen global
1106 if (root->fullscreen_global && container != root->fullscreen_global &&
1107 !container_has_ancestor(container, root->fullscreen_global)) {
1108 // Unless it's a transient container
1109 if (!container_is_transient_for(container, root->fullscreen_global)) {
1110 return;
1111 }
1112 }
1113 1151
1114 struct sway_output *new_output = 1152 struct sway_output *new_output =
1115 new_workspace ? new_workspace->output : NULL; 1153 new_workspace ? new_workspace->output : NULL;
@@ -1135,10 +1173,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 1173 // Put the container parents on the focus stack, then the workspace, then
1136 // the focused container. 1174 // the focused container.
1137 if (container) { 1175 if (container) {
1138 struct sway_container *parent = container->parent; 1176 struct sway_container *parent = container->pending.parent;
1139 while (parent) { 1177 while (parent) {
1140 seat_set_raw_focus(seat, &parent->node); 1178 seat_set_raw_focus(seat, &parent->node);
1141 parent = parent->parent; 1179 parent = parent->pending.parent;
1142 } 1180 }
1143 } 1181 }
1144 if (new_workspace) { 1182 if (new_workspace) {
@@ -1234,6 +1272,7 @@ void seat_set_focus_surface(struct sway_seat *seat,
1234 wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat); 1272 wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat);
1235 } 1273 }
1236 1274
1275 sway_input_method_relay_set_focus(&seat->im_relay, surface);
1237 seat_tablet_pads_notify_enter(seat, surface); 1276 seat_tablet_pads_notify_enter(seat, surface);
1238} 1277}
1239 1278
@@ -1326,7 +1365,7 @@ struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat,
1326 struct sway_node *node = current->node; 1365 struct sway_node *node = current->node;
1327 if (node->type == N_CONTAINER && 1366 if (node->type == N_CONTAINER &&
1328 !container_is_floating_or_child(node->sway_container) && 1367 !container_is_floating_or_child(node->sway_container) &&
1329 node->sway_container->workspace == workspace) { 1368 node->sway_container->pending.workspace == workspace) {
1330 return node->sway_container; 1369 return node->sway_container;
1331 } 1370 }
1332 } 1371 }
@@ -1343,7 +1382,7 @@ struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat,
1343 struct sway_node *node = current->node; 1382 struct sway_node *node = current->node;
1344 if (node->type == N_CONTAINER && 1383 if (node->type == N_CONTAINER &&
1345 container_is_floating_or_child(node->sway_container) && 1384 container_is_floating_or_child(node->sway_container) &&
1346 node->sway_container->workspace == workspace) { 1385 node->sway_container->pending.workspace == workspace) {
1347 return node->sway_container; 1386 return node->sway_container;
1348 } 1387 }
1349 } 1388 }
@@ -1391,7 +1430,7 @@ struct sway_workspace *seat_get_focused_workspace(struct sway_seat *seat) {
1391 return NULL; 1430 return NULL;
1392 } 1431 }
1393 if (focus->type == N_CONTAINER) { 1432 if (focus->type == N_CONTAINER) {
1394 return focus->sway_container->workspace; 1433 return focus->sway_container->pending.workspace;
1395 } 1434 }
1396 if (focus->type == N_WORKSPACE) { 1435 if (focus->type == N_WORKSPACE) {
1397 return focus->sway_workspace; 1436 return focus->sway_workspace;
@@ -1404,8 +1443,8 @@ struct sway_workspace *seat_get_last_known_workspace(struct sway_seat *seat) {
1404 wl_list_for_each(current, &seat->focus_stack, link) { 1443 wl_list_for_each(current, &seat->focus_stack, link) {
1405 struct sway_node *node = current->node; 1444 struct sway_node *node = current->node;
1406 if (node->type == N_CONTAINER && 1445 if (node->type == N_CONTAINER &&
1407 node->sway_container->workspace) { 1446 node->sway_container->pending.workspace) {
1408 return node->sway_container->workspace; 1447 return node->sway_container->pending.workspace;
1409 } else if (node->type == N_WORKSPACE) { 1448 } else if (node->type == N_WORKSPACE) {
1410 return node->sway_workspace; 1449 return node->sway_workspace;
1411 } 1450 }