diff --git a/include/labwc.h b/include/labwc.h index 5946c495..a405a307 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -213,6 +213,7 @@ struct view { enum view_type type; const struct view_impl *impl; struct wl_list link; + struct output *output; union { struct wlr_xdg_surface *xdg_surface; @@ -376,8 +377,7 @@ void view_for_each_surface(struct view *view, wlr_surface_iterator_func_t iterator, void *user_data); void view_for_each_popup_surface(struct view *view, wlr_surface_iterator_func_t iterator, void *data); -void view_output_enter(struct view *view, struct wlr_output *wlr_output); -void view_output_leave(struct view *view, struct wlr_output *wlr_output); +void view_discover_output(struct view *view); void view_move_to_edge(struct view *view, const char *direction); void view_snap_to_edge(struct view *view, const char *direction); const char *view_get_string_prop(struct view *view, const char *prop); diff --git a/src/view.c b/src/view.c index fdbeb842..5d55cb5d 100644 --- a/src/view.c +++ b/src/view.c @@ -23,6 +23,7 @@ view_move_resize(struct view *view, struct wlr_box geo) view->impl->configure(view, geo); } ssd_update_title(view); + view_discover_output(view); } void @@ -31,6 +32,7 @@ view_move(struct view *view, double x, double y) if (view->impl->move) { view->impl->move(view, x, y); } + view_discover_output(view); } #define MIN_VIEW_WIDTH (100) @@ -254,7 +256,7 @@ view_border(struct view *view) return border; } -void +static void surface_enter_for_each_surface(struct wlr_surface *surface, int sx, int sy, void *user_data) { @@ -262,7 +264,7 @@ surface_enter_for_each_surface(struct wlr_surface *surface, int sx, int sy, wlr_surface_send_enter(surface, wlr_output); } -void +static void surface_leave_for_each_surface(struct wlr_surface *surface, int sx, int sy, void *user_data) { @@ -270,7 +272,7 @@ surface_leave_for_each_surface(struct wlr_surface *surface, int sx, int sy, wlr_surface_send_leave(surface, wlr_output); } -void +static void view_output_enter(struct view *view, struct wlr_output *wlr_output) { view_for_each_surface(view, surface_enter_for_each_surface, @@ -281,7 +283,7 @@ view_output_enter(struct view *view, struct wlr_output *wlr_output) } } -void +static void view_output_leave(struct view *view, struct wlr_output *wlr_output) { view_for_each_surface(view, surface_leave_for_each_surface, @@ -292,6 +294,25 @@ view_output_leave(struct view *view, struct wlr_output *wlr_output) } } +/* + * At present, a view can only 'enter' one output at a time, although the view + * may span multiple outputs. Ideally we would handle multiple outputs, but + * this method is the simplest form of what we want. + */ +void +view_discover_output(struct view *view) +{ + struct output *old_output = view->output; + struct output *new_output = view_output(view); + if (old_output != new_output) { + view->output = new_output; + view_output_enter(view, new_output->wlr_output); + if (old_output) { + view_output_leave(view, old_output->wlr_output); + } + } +} + void view_move_to_edge(struct view *view, const char *direction) { diff --git a/src/xdg.c b/src/xdg.c index c63167ae..8a64962d 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -343,8 +343,7 @@ xdg_toplevel_view_map(struct view *view) current.link) { view_subsurface_create(view, subsurface); } - struct wlr_output *wlr_output = view_wlr_output(view); - view_output_enter(view, wlr_output); + view_discover_output(view); view->been_mapped = true; } diff --git a/src/xwayland.c b/src/xwayland.c index f74c1b6c..ca22343c 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -257,8 +257,7 @@ map(struct view *view) view->y = box.y; view_center(view); - struct wlr_output *wlr_output = view_wlr_output(view); - view_output_enter(view, wlr_output); + view_discover_output(view); view->been_mapped = true; }