kranewl

A wlroots-based dynamic Wayland compositor, written in C++, configurable with Lua
git clone git://git.deurzen.net/kranewl
Log | Files | Refs | LICENSE

commit a00db66c3a103cc78ea399549c96fb056d86823e
parent 47f9be1a377441f696e3754c0af232f23ef33efb
Author: deurzen <max@deurzen.net>
Date:   Sun, 28 Aug 2022 18:42:17 +0200

implements view fullscreen handling

Diffstat:
Minclude/kranewl/placement.hh | 1+
Minclude/kranewl/tree/view.hh | 2+-
Minclude/kranewl/tree/xdg-view.hh | 2+-
Minclude/kranewl/tree/xwayland-view.hh | 2+-
Msrc/kranewl/model.cc | 54+++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/kranewl/tree/xdg-view.cc | 23++++++++++++++++++-----
Msrc/kranewl/tree/xwayland-view.cc | 21+++++++++++++++++----
Msrc/kranewl/workspace.cc | 2+-
8 files changed, 85 insertions(+), 22 deletions(-)

diff --git a/include/kranewl/placement.hh b/include/kranewl/placement.hh @@ -28,6 +28,7 @@ struct Placement final { { Free, Tile, + Fullscreen, }; PlacementMethod method; diff --git a/include/kranewl/tree/view.hh b/include/kranewl/tree/view.hh @@ -69,7 +69,7 @@ typedef struct View : public Node { virtual void focus(Toggle) = 0; virtual void activate(Toggle) = 0; - virtual void set_fullscreen(Toggle) = 0; + virtual void effectuate_fullscreen(bool) = 0; virtual void configure(Region const&, Extents const&, bool) = 0; virtual void close() = 0; diff --git a/include/kranewl/tree/xdg-view.hh b/include/kranewl/tree/xdg-view.hh @@ -29,7 +29,7 @@ typedef struct XDGView final : public View { void focus(Toggle) override; void activate(Toggle) override; - void set_fullscreen(Toggle) override; + void effectuate_fullscreen(bool) override; void configure(Region const&, Extents const&, bool) override; void close() override; diff --git a/include/kranewl/tree/xwayland-view.hh b/include/kranewl/tree/xwayland-view.hh @@ -36,7 +36,7 @@ typedef struct XWaylandView final : public View { void focus(Toggle) override; void activate(Toggle) override; - void set_fullscreen(Toggle) override; + void effectuate_fullscreen(bool) override; void configure(Region const&, Extents const&, bool) override; void close() override; diff --git a/src/kranewl/model.cc b/src/kranewl/model.cc @@ -371,6 +371,14 @@ Model::place_view(Placement& placement) move_view_to_track(view, SceneLayer::SCENE_LAYER_TILE); break; } + case Placement::PlacementMethod::Fullscreen: + { + view->set_free(false); + view->set_free_decoration(FREE_DECORATION); + view->set_tile_decoration(placement.decoration); + move_view_to_track(view, SceneLayer::SCENE_LAYER_OVERLAY); + break; + } } view->unmap(); @@ -395,6 +403,13 @@ Model::place_view(Placement& placement) move_view_to_track(view, SceneLayer::SCENE_LAYER_TILE); break; } + case Placement::PlacementMethod::Fullscreen: + { + view->set_tile_decoration(placement.decoration); + view->set_tile_region(*placement.region); + move_view_to_track(view, SceneLayer::SCENE_LAYER_OVERLAY); + break; + } } spdlog::info( @@ -554,9 +569,15 @@ Model::relayer_views(Workspace_ptr workspace) { for (View_ptr view : *workspace) { if (view->free()) { - if (view->scene_layer() != SceneLayer::SCENE_LAYER_FREE) + if (view->scene_layer() != SceneLayer::SCENE_LAYER_FREE) { move_view_to_track(view, SceneLayer::SCENE_LAYER_FREE); view->lower(); + } + } else if (view->fullscreen()) { + if (view->scene_layer() != SceneLayer::SCENE_LAYER_OVERLAY) { + move_view_to_track(view, SceneLayer::SCENE_LAYER_OVERLAY); + view->lower(); + } } else { if (view->scene_layer() != SceneLayer::SCENE_LAYER_TILE) { move_view_to_track(view, SceneLayer::SCENE_LAYER_TILE); @@ -1451,10 +1472,17 @@ Model::set_fullscreen_view(Toggle toggle, View_ptr view) if (view->fullscreen()) return; - view->set_fullscreen(true); - // TODO: set fullscreen state + view->effectuate_fullscreen(true); m_fullscreen_map[view] = view->free_region(); + if (!view->contained()) + move_view_to_track(view, SceneLayer::SCENE_LAYER_OVERLAY); + + if (view == mp_focus) { + activate_track(SceneLayer::SCENE_LAYER_OVERLAY); + view->raise(); + } + break; } case Toggle::Off: @@ -1465,10 +1493,20 @@ Model::set_fullscreen_view(Toggle toggle, View_ptr view) if (!view->contained()) view->set_free_region(m_fullscreen_map.at(view)); - view->set_fullscreen(false); - // TODO: unset fullscreen state + view->effectuate_fullscreen(false); m_fullscreen_map.erase(view); + const SceneLayer layer = view->free() + ? SceneLayer::SCENE_LAYER_FREE + : SceneLayer::SCENE_LAYER_TILE; + + move_view_to_track(view, layer); + + if (view == mp_focus) { + activate_track(layer); + view->raise(); + } + break; } case Toggle::Reverse: @@ -1486,11 +1524,9 @@ Model::set_fullscreen_view(Toggle toggle, View_ptr view) } Workspace_ptr workspace = view->mp_workspace; - apply_layout(workspace); + if (workspace) + apply_layout(workspace); - if (view == mp_focus) - // TODO: separate layer? - move_view_to_track(view, SceneLayer::SCENE_LAYER_OVERLAY); } void diff --git a/src/kranewl/tree/xdg-view.cc b/src/kranewl/tree/xdg-view.cc @@ -196,10 +196,14 @@ XDGView::activate(Toggle toggle) } void -XDGView::set_fullscreen(Toggle) +XDGView::effectuate_fullscreen(bool fullscreen) { TRACE(); - // TODO + + if (View::fullscreen() != fullscreen) { + set_fullscreen(fullscreen); + wlr_xdg_toplevel_set_fullscreen(mp_wlr_xdg_surface, fullscreen); + } } void @@ -251,24 +255,33 @@ XDGView::handle_commit(struct wl_listener* listener, void* data) } void -XDGView::handle_request_move(struct wl_listener* listener, void* data) +XDGView::handle_request_move(struct wl_listener*, void*) { TRACE(); } void -XDGView::handle_request_resize(struct wl_listener* listener, void* data) +XDGView::handle_request_resize(struct wl_listener*, void*) { TRACE(); } void -XDGView::handle_request_fullscreen(struct wl_listener* listener, void* data) +XDGView::handle_request_fullscreen(struct wl_listener* listener, void*) { TRACE(); + XDGView_ptr view = wl_container_of(listener, view, ml_request_fullscreen); + struct wlr_xdg_toplevel* xdg_toplevel = view->mp_wlr_xdg_toplevel; + + view->mp_model->set_fullscreen_view( + xdg_toplevel->requested.fullscreen + ? Toggle::On + : Toggle::Off, + view + ); } void diff --git a/src/kranewl/tree/xwayland-view.cc b/src/kranewl/tree/xwayland-view.cc @@ -239,10 +239,14 @@ XWaylandView::activate(Toggle toggle) } void -XWaylandView::set_fullscreen(Toggle) +XWaylandView::effectuate_fullscreen(bool fullscreen) { TRACE(); - // TODO + + if (View::fullscreen() != fullscreen) { + set_fullscreen(fullscreen); + wlr_xwayland_surface_set_fullscreen(mp_wlr_xwayland_surface, fullscreen); + } } void @@ -459,10 +463,19 @@ XWaylandView::handle_request_configure(struct wl_listener* listener, void* data) } void -XWaylandView::handle_request_fullscreen(struct wl_listener*, void*) +XWaylandView::handle_request_fullscreen(struct wl_listener* listener, void*) { TRACE(); - // TODO + + XWaylandView_ptr view = wl_container_of(listener, view, ml_request_fullscreen); + struct wlr_xwayland_surface* xwayland_surface = view->mp_wlr_xwayland_surface; + + view->mp_model->set_fullscreen_view( + xwayland_surface->fullscreen + ? Toggle::On + : Toggle::Off, + view + ); } void diff --git a/src/kranewl/workspace.cc b/src/kranewl/workspace.cc @@ -780,7 +780,7 @@ Workspace::arrange(Region region) const std::back_inserter(placements), [region](const View_ptr view) -> Placement { return Placement { - Placement::PlacementMethod::Tile, + Placement::PlacementMethod::Fullscreen, view, NO_DECORATION, region