]> git.mdlowis.com Git - proto/labwc.git/commitdiff
src/foreign.c: track outputs
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Thu, 2 Feb 2023 06:16:57 +0000 (07:16 +0100)
committerConsolatis <35009135+Consolatis@users.noreply.github.com>
Thu, 2 Feb 2023 12:26:53 +0000 (13:26 +0100)
Fixes #744

include/labwc.h
src/foreign.c
src/view.c

index 6212a09f734b978ed519c302c53573dd466d7dbe..b8d839e61f09c4077366a80cddf077f8b2b3b9a2 100644 (file)
@@ -345,6 +345,7 @@ void xdg_toplevel_decoration(struct wl_listener *listener, void *data);
 void xdg_surface_new(struct wl_listener *listener, void *data);
 
 void foreign_toplevel_handle_create(struct view *view);
+void foreign_toplevel_update_outputs(struct view *view);
 
 /*
  * desktop.c routines deal with a collection of views
index 1a1f376e9ecb7bb5713607b3bb82ac55f0635bc3..86ff27f083af0ba4c944b2fd1e9c2ae8156b6be1 100644 (file)
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
+#include <assert.h>
 #include "labwc.h"
 #include "view.h"
 #include "workspaces.h"
@@ -74,14 +75,6 @@ foreign_toplevel_handle_create(struct view *view)
                return;
        }
 
-       struct wlr_output *wlr_output = view_wlr_output(view);
-       if (!wlr_output) {
-               wlr_log(WLR_ERROR, "no wlr_output for (%s)",
-                       view_get_string_prop(view, "title"));
-               return;
-       }
-       wlr_foreign_toplevel_handle_v1_output_enter(toplevel->handle, wlr_output);
-
        toplevel->maximize.notify = handle_request_maximize;
        wl_signal_add(&toplevel->handle->events.request_maximize,
                &toplevel->maximize);
@@ -105,3 +98,33 @@ foreign_toplevel_handle_create(struct view *view)
        toplevel->destroy.notify = handle_destroy;
        wl_signal_add(&toplevel->handle->events.destroy, &toplevel->destroy);
 }
+
+/*
+ * Loop over all outputs and notify foreign_toplevel clients about changes.
+ * wlr_foreign_toplevel_handle_v1_output_xxx() keeps track of the active
+ * outputs internally and merges the events. It also listens to output
+ * destroy events so its fine to just relay the current state and let
+ * wlr_foreign_toplevel handle the rest.
+ */
+void
+foreign_toplevel_update_outputs(struct view *view)
+{
+       assert(view->toplevel.handle);
+
+       struct wlr_box view_geo = { view->x, view->y, view->w, view->h };
+       struct wlr_output_layout *layout = view->server->output_layout;
+
+       struct output *output;
+       wl_list_for_each(output, &view->server->outputs, link) {
+               if (output->wlr_output->enabled && !output->leased) {
+                       if (wlr_output_layout_intersects(layout,
+                                       output->wlr_output, &view_geo)) {
+                               wlr_foreign_toplevel_handle_v1_output_enter(
+                                       view->toplevel.handle, output->wlr_output);
+                               continue;
+                       }
+               }
+               wlr_foreign_toplevel_handle_v1_output_leave(
+                       view->toplevel.handle, output->wlr_output);
+       }
+}
index d9108b2b13d7b98a0aee67c729c4d620567aa55c..8f9d005535686ad29b93e513ad439d3d5b8c2ab3 100644 (file)
@@ -156,6 +156,9 @@ view_moved(struct view *view)
        view_discover_output(view);
        ssd_update_geometry(view->ssd);
        cursor_update_focus(view->server);
+       if (view->toplevel.handle) {
+               foreign_toplevel_update_outputs(view);
+       }
 }
 
 /* N.B. Use view_move() if not resizing. */
@@ -754,23 +757,8 @@ view_adjust_for_layout_change(struct view *view)
                        view_center(view);
                }
        }
-}
-
-static void
-view_output_enter(struct view *view, struct wlr_output *wlr_output)
-{
        if (view->toplevel.handle) {
-               wlr_foreign_toplevel_handle_v1_output_enter(
-                       view->toplevel.handle, wlr_output);
-       }
-}
-
-static void
-view_output_leave(struct view *view, struct wlr_output *wlr_output)
-{
-       if (view->toplevel.handle) {
-               wlr_foreign_toplevel_handle_v1_output_leave(
-                       view->toplevel.handle, wlr_output);
+               foreign_toplevel_update_outputs(view);
        }
 }
 
@@ -783,24 +771,13 @@ void
 view_discover_output(struct view *view)
 {
        assert(view);
-       struct output *old_output = view->output;
-       struct output *new_output = view_output(view);
-       if (old_output != new_output) {
-               view->output = new_output;
-               if (new_output) {
-                       view_output_enter(view, new_output->wlr_output);
-               }
-               if (old_output) {
-                       view_output_leave(view, old_output->wlr_output);
-               }
-       }
+       view->output = view_output(view);
 }
 
 void
 view_on_output_destroy(struct view *view)
 {
        assert(view);
-       view_output_leave(view, view->output->wlr_output);
        view->output = NULL;
 }