]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Support openbox style "cycle window"
authorJohan Malm <jgm323@gmail.com>
Mon, 18 May 2020 19:54:25 +0000 (20:54 +0100)
committerJohan Malm <jgm323@gmail.com>
Mon, 18 May 2020 19:54:25 +0000 (20:54 +0100)
We still use alt-F2, but it now feels like alt-tab does.

labwc.h
server.c
view.c
xdg.c
xwl.c

diff --git a/labwc.h b/labwc.h
index 871589f7ab81cfedae00c6a1f478b7f1edd95a7e..05d5755cd714ec1cd98e8bfdf9d2d406b8eaccbb 100644 (file)
--- a/labwc.h
+++ b/labwc.h
@@ -68,6 +68,8 @@ struct server {
        struct wl_listener request_cursor;
        struct wl_listener request_set_selection;
        struct wl_list keyboards;
+
+       /* cursor interactive */
        enum cursor_mode cursor_mode;
        struct view *grabbed_view;
        double grab_x, grab_y;
@@ -139,19 +141,15 @@ void xwl_surface_configure(struct wl_listener *listener, void *data);
 void xwl_surface_new(struct wl_listener *listener, void *data);
 
 bool view_want_deco(struct view *view);
-void view_focus_last_toplevel(struct server *server);
 void view_focus(struct view *view);
-void view_focus_next_toplevel(struct view *current);
 void begin_interactive(struct view *view, enum cursor_mode mode,
                       uint32_t edges);
-bool is_toplevel(struct view *view);
+struct view *view_front_toplevel(struct server *server);
+struct view *next_toplevel(struct view *current);
 struct view *view_at(struct server *server, double lx, double ly,
                     struct wlr_surface **surface, double *sx, double *sy,
                     int *view_area);
 
-/* TODO: try to refactor to remove from header file */
-struct view *first_toplevel(struct server *server);
-
 void server_new_input(struct wl_listener *listener, void *data);
 void seat_request_cursor(struct wl_listener *listener, void *data);
 void seat_request_set_selection(struct wl_listener *listener, void *data);
index 3ec0a831b724df50324430f530916a7acbb0e24e..c5eef4727613d4a849a5f8bfc6ba3e2254c8cdbe 100644 (file)
--- a/server.c
+++ b/server.c
@@ -1,5 +1,8 @@
 #include "labwc.h"
 
+static bool in_alt_tab_mode;
+static struct view *alt_tab_view;
+
 static void keyboard_handle_modifiers(struct wl_listener *listener, void *data)
 {
        /* This event is raised when a modifier key, such as shift or alt, is
@@ -33,7 +36,9 @@ static bool handle_keybinding(struct server *server, xkb_keysym_t sym)
                break;
        case XKB_KEY_F1:
        case XKB_KEY_F2:
-               view_focus_last_toplevel(server);
+               in_alt_tab_mode = true;
+               alt_tab_view = next_toplevel(view_front_toplevel(server));
+               fprintf(stderr, "alt_tab_view=%p\n", (void *)alt_tab_view);
                break;
        case XKB_KEY_F3:
                if (fork() == 0) {
@@ -41,8 +46,8 @@ static bool handle_keybinding(struct server *server, xkb_keysym_t sym)
                }
                break;
        case XKB_KEY_F6:
-               begin_interactive(first_toplevel(server), TINYWL_CURSOR_MOVE,
-                                 0);
+               begin_interactive(view_front_toplevel(server),
+                                 TINYWL_CURSOR_MOVE, 0);
                break;
        case XKB_KEY_F12:
                dbg_show_views(server);
@@ -71,6 +76,23 @@ static void keyboard_handle_key(struct wl_listener *listener, void *data)
        bool handled = false;
        uint32_t modifiers =
                wlr_keyboard_get_modifiers(keyboard->device->keyboard);
+
+       if (in_alt_tab_mode) {
+               if ((syms[0] == XKB_KEY_Alt_L) &&
+                   event->state == WLR_KEY_RELEASED) {
+                       /* end cycle */
+                       in_alt_tab_mode = false;
+                       view_focus(alt_tab_view);
+               } else if (event->state == WLR_KEY_PRESSED) {
+                       /* cycle to next */
+                       alt_tab_view = next_toplevel(alt_tab_view);
+                       fprintf(stderr, "alt_tab_view=%p\n",
+                               (void *)alt_tab_view);
+                       return;
+               }
+       }
+
+       /* Handle compositor key bindings */
        if ((modifiers & WLR_MODIFIER_ALT) && event->state == WLR_KEY_PRESSED) {
                /* If alt is held down and this button was _pressed_, we attempt
                 * to process it as a compositor keybinding. */
@@ -78,7 +100,6 @@ static void keyboard_handle_key(struct wl_listener *listener, void *data)
                        handled = handle_keybinding(server, syms[i]);
                }
        }
-
        if (!handled) {
                /* Otherwise, we pass it along to the client. */
                wlr_seat_set_keyboard(seat, keyboard->device);
diff --git a/view.c b/view.c
index edddebcad81a60c33a709a1f78b31baa957fac35..966b8690e5476f6f1d7ae15d7f1f3942701a5c15 100644 (file)
--- a/view.c
+++ b/view.c
@@ -1,6 +1,6 @@
 #include "labwc.h"
 
-bool is_toplevel(struct view *view)
+static bool is_toplevel(struct view *view)
 {
        switch (view->type) {
        case LAB_XDG_SHELL_VIEW:
@@ -11,61 +11,18 @@ bool is_toplevel(struct view *view)
        return false;
 }
 
-struct view *first_toplevel(struct server *server)
-{
-       struct view *view;
-
-       wl_list_for_each (view, &server->views, link) {
-               if (!view->been_mapped) {
-                       continue;
-               }
-               if (is_toplevel(view)) {
-                       return view;
-               }
-       }
-       fprintf(stderr, "warn: found no toplevel view (%s)\n", __func__);
-       return NULL;
-}
-
-static struct view *last_toplevel(struct server *server)
-{
-       struct view *view;
-
-       wl_list_for_each_reverse (view, &server->views, link) {
-               if (!view->been_mapped)
-                       continue;
-               if (is_toplevel(view))
-                       return view;
-       }
-       /* no top-level view */
-       return NULL;
-}
-
-void view_focus_last_toplevel(struct server *server)
-{
-       /* TODO: write view_nr_toplevel_views() */
-       if (wl_list_length(&server->views) < 2)
-               return;
-       struct view *view = last_toplevel(server);
-       view_focus(view);
-}
-
-static struct view *next_toplevel(struct view *current)
-{
-       struct view *tmp = current;
-
-       do {
-               tmp = wl_container_of(tmp->link.next, tmp, link);
-       } while (!tmp->been_mapped || !is_toplevel(tmp));
-       return tmp;
-}
-
-/* Original function name - suggest we keep it */
-void view_focus_next_toplevel(struct view *current)
+bool view_want_deco(struct view *view)
 {
-       struct view *view;
-       view = next_toplevel(current);
-       view_focus(view);
+       if (view->type != LAB_XWAYLAND_VIEW)
+               return false;
+       if (!is_toplevel(view))
+               return false;
+       if (view->xwayland_surface->override_redirect)
+               return false;
+       if (view->xwayland_surface->decorations !=
+           WLR_XWAYLAND_SURFACE_DECORATIONS_ALL)
+               return false;
+       return true;
 }
 
 static void move_to_front(struct view *view)
@@ -128,20 +85,6 @@ void view_focus(struct view *view)
                                       &keyboard->modifiers);
 }
 
-bool view_want_deco(struct view *view)
-{
-       if (view->type != LAB_XWAYLAND_VIEW)
-               return false;
-       if (!is_toplevel(view))
-               return false;
-       if (view->xwayland_surface->override_redirect)
-               return false;
-       if (view->xwayland_surface->decorations !=
-           WLR_XWAYLAND_SURFACE_DECORATIONS_ALL)
-               return false;
-       return true;
-}
-
 void begin_interactive(struct view *view, enum cursor_mode mode, uint32_t edges)
 {
        /* This function sets up an interactive move or resize operation, where
@@ -184,6 +127,28 @@ void begin_interactive(struct view *view, enum cursor_mode mode, uint32_t edges)
        }
 }
 
+struct view *view_front_toplevel(struct server *server)
+{
+       struct view *view;
+       wl_list_for_each (view, &server->views, link) {
+               if (!view->been_mapped)
+                       continue;
+               if (is_toplevel(view))
+                       return view;
+       }
+       return NULL;
+}
+
+struct view *next_toplevel(struct view *current)
+{
+       /* FIXME: write nr_toplevels() */
+       struct view *view = current;
+       do {
+               view = wl_container_of(view->link.next, view, link);
+       } while (!view->been_mapped || !is_toplevel(view));
+       return view;
+}
+
 static bool _view_at(struct view *view, double lx, double ly,
                     struct wlr_surface **surface, double *sx, double *sy)
 {
diff --git a/xdg.c b/xdg.c
index 8234eb9092a11ae5aa362af3e2c4d830f006a316..39310d4f4891ec9262bcaac2ade19ac4de2e9928 100644 (file)
--- a/xdg.c
+++ b/xdg.c
@@ -61,7 +61,7 @@ void xdg_surface_unmap(struct wl_listener *listener, void *data)
 {
        struct view *view = wl_container_of(listener, view, unmap);
        view->mapped = false;
-       view_focus_next_toplevel(view);
+       view_focus(next_toplevel(view));
 }
 
 void xdg_surface_destroy(struct wl_listener *listener, void *data)
diff --git a/xwl.c b/xwl.c
index 9294377d841eb81dc9879982cb6e2577fb7ffcc4..c6e7806f49c124af930379a9ce161d284b55f753 100644 (file)
--- a/xwl.c
+++ b/xwl.c
@@ -49,7 +49,12 @@ void xwl_surface_unmap(struct wl_listener *listener, void *data)
 {
        struct view *view = wl_container_of(listener, view, unmap);
        view->mapped = false;
-       view_focus_next_toplevel(view);
+       /*
+        * Note that if 'view' is not a toplevel view, the 'front' toplevel view
+        * will be focussed on; but if 'view' is a toplevel view, the 'next'
+        * will be focussed on.
+        */
+       view_focus(next_toplevel(view));
 }
 
 void xwl_surface_destroy(struct wl_listener *listener, void *data)