Merge pull request #747 from Consolatis/feature/foreign_output_tracking

src/foreign.c: track outputs
This commit is contained in:
Johan Malm 2023-02-03 21:59:12 +00:00 committed by GitHub
commit 6a51764884
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 39 deletions

View 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

View file

@ -121,8 +121,6 @@ void view_move_resize(struct view *view, struct wlr_box geo);
void view_move(struct view *view, int x, int y);
void view_moved(struct view *view);
void view_minimize(struct view *view, bool minimized);
/* view_wlr_output - return the output that a view is mostly on */
struct wlr_output *view_wlr_output(struct view *view);
void view_store_natural_geometry(struct view *view);
void view_center(struct view *view);
void view_restore_to(struct view *view, struct wlr_box geometry);

View 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);
}
}

View 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. */
@ -217,7 +220,7 @@ view_minimize(struct view *view, bool minimized)
}
/* view_wlr_output - return the output that a view is mostly on */
struct wlr_output *
static struct wlr_output *
view_wlr_output(struct view *view)
{
assert(view);
@ -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;
}