Release focus when panels drop exclusivity
b6e528e08c94a67eaa54700cd174f6fc55b91084
1 parent
1e7a40ee
swm.c
+25 -1
| 1868 | 1868 | wlr_scene_rect_set_size(l->dim, full_area.width, full_area.height); |
|
| 1869 | 1869 | } |
|
| 1870 | 1870 | } |
|
| 1871 | 1871 | } |
|
| 1872 | 1872 | ||
| 1873 | + | /* Track the layer surface with exclusive keyboard focus. */ |
|
| 1874 | + | static bool layer_focus_update(monitor_t *m, layer_surface_t *target) { |
|
| 1875 | + | layer_surface_t *l; |
|
| 1876 | + | size_t i; |
|
| 1877 | + | ||
| 1878 | + | if (target) { |
|
| 1879 | + | exclusive_focus = target; |
|
| 1880 | + | return false; |
|
| 1881 | + | } |
|
| 1882 | + | if (!exclusive_focus) |
|
| 1883 | + | return false; |
|
| 1884 | + | ||
| 1885 | + | for (i = 0; i < LENGTH(m->layers); i++) |
|
| 1886 | + | wl_list_for_each(l, &m->layers[i], link) { |
|
| 1887 | + | if (l == exclusive_focus) { |
|
| 1888 | + | exclusive_focus = nullptr; |
|
| 1889 | + | return true; |
|
| 1890 | + | } |
|
| 1891 | + | } |
|
| 1892 | + | return false; |
|
| 1893 | + | } |
|
| 1894 | + | ||
| 1873 | 1895 | /* Arrange desktop layers and give keyboard focus to the highest eligible surface. */ |
|
| 1874 | 1896 | void arrange_layers(monitor_t *m) { |
|
| 1875 | 1897 | int i; |
|
| 1876 | 1898 | struct wlr_box usable_area = m->m; |
|
| 1877 | 1899 | layer_surface_t *l; |
| 1903 | 1925 | ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE || |
|
| 1904 | 1926 | !l->mapped) |
|
| 1905 | 1927 | continue; |
|
| 1906 | 1928 | /* Deactivate the focused client. */ |
|
| 1907 | 1929 | focus_client(nullptr, 0); |
|
| 1908 | - | exclusive_focus = l; |
|
| 1930 | + | layer_focus_update(m, l); |
|
| 1909 | 1931 | client_notify_enter(l->layer_surface->surface, wlr_seat_get_keyboard(seat)); |
|
| 1910 | 1932 | return; |
|
| 1911 | 1933 | } |
|
| 1912 | 1934 | } |
|
| 1935 | + | if (layer_focus_update(m, nullptr)) |
|
| 1936 | + | focus_client(focus_top(selmon), 1); |
|
| 1913 | 1937 | } |
|
| 1914 | 1938 | ||
| 1915 | 1939 | /* Expand $NAME variables into caller-owned stack storage. */ |
|
| 1916 | 1940 | void expand_argv(const char *const *argv, char **expanded, char *storage) { |
|
| 1917 | 1941 | size_t i, remaining = MAX_COMMAND_SIZE, size; |
test/unit.c
+16 -0
| 872 | 872 | }; |
|
| 873 | 873 | ||
| 874 | 874 | assert(layer_surface_output_monitor(&wrapper) == &monitor); |
|
| 875 | 875 | } |
|
| 876 | 876 | ||
| 877 | + | /* Verify a layer relinquishing exclusivity releases keyboard focus. */ |
|
| 878 | + | static void test_layer_focus_release(void) { |
|
| 879 | + | monitor_t monitor = {}; |
|
| 880 | + | layer_surface_t layer = { .mon = &monitor }; |
|
| 881 | + | size_t i; |
|
| 882 | + | ||
| 883 | + | for (i = 0; i < LENGTH(monitor.layers); i++) |
|
| 884 | + | wl_list_init(&monitor.layers[i]); |
|
| 885 | + | wl_list_insert(&monitor.layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &layer.link); |
|
| 886 | + | ||
| 887 | + | exclusive_focus = &layer; |
|
| 888 | + | assert(layer_focus_update(&monitor, nullptr)); |
|
| 889 | + | assert(exclusive_focus == nullptr); |
|
| 890 | + | } |
|
| 891 | + | ||
| 877 | 892 | /* Verify deleting X11 WM_HINTS clears a previously urgent window. */ |
|
| 878 | 893 | static void test_x11_urgency(void) { |
|
| 879 | 894 | struct wlr_xwayland_surface xsurface = {}; |
|
| 880 | 895 | client_t client = { .type = X11, .is_urgent = true }; |
|
| 881 | 896 |
| 1108 | 1123 | { "window-state", test_window_state_storage }, |
|
| 1109 | 1124 | { "child-reaping", test_child_reaping }, |
|
| 1110 | 1125 | { "spawn-tracking", test_spawn_tracking }, |
|
| 1111 | 1126 | { "layer-unmap-monitor", test_layer_unmap_monitor }, |
|
| 1112 | 1127 | { "command-failure-notification", test_command_failure_notification }, |
|
| 1128 | + | { "layer-focus-release", test_layer_focus_release }, |
|
| 1113 | 1129 | { "commands-without-clients", test_commands_without_clients }, |
|
| 1114 | 1130 | { "small-helpers", test_small_helpers }, |
|
| 1115 | 1131 | { "pointer-grab-button", test_pointer_grab_button }, |
|
| 1116 | 1132 | { "client-accessors", test_client_accessors }, |
|
| 1117 | 1133 | { "autostart", test_autostart_execution }, |