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 b7cfa064e7581bddc9444117000625d715295ad8
parent 78d93d18a1e9ff994e014e80b8a151630b52f20c
Author: deurzen <m.deurzen@tum.de>
Date:   Sun, 22 May 2022 19:09:50 +0200

adds view structures

Diffstat:
Minclude/kranewl/common.hh | 1-
Minclude/kranewl/geometry.hh | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Minclude/kranewl/input/seat.hh | 9+++++----
Minclude/kranewl/layout.hh | 38+++++++++++++++++++-------------------
Minclude/kranewl/model.hh | 29++++++++++++++---------------
Minclude/kranewl/placement.hh | 8++++----
Minclude/kranewl/server.hh | 2--
Minclude/kranewl/tree/client.hh | 1+
Minclude/kranewl/tree/container.hh | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Minclude/kranewl/tree/node.hh | 20++++++++++----------
Minclude/kranewl/tree/output.hh | 4++--
Ainclude/kranewl/tree/popup.hh | 14++++++++++++++
Dinclude/kranewl/tree/root.hh | 41-----------------------------------------
Ainclude/kranewl/tree/subsurface.hh | 11+++++++++++
Minclude/kranewl/tree/view.hh | 166++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Ainclude/kranewl/tree/xdg_view.hh | 20++++++++++++++++++++
Ainclude/kranewl/tree/xwayland_view.hh | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Minclude/kranewl/workspace.hh | 88++++++++++++++++++++++++++++++++++++++++---------------------------------------
Minclude/version.hh | 4++--
Msrc/kranewl/input/seat.cc | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Msrc/kranewl/layout.cc | 140++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/kranewl/model.cc | 36+++++++++++++++++-------------------
Msrc/kranewl/server.cc | 51++++++++++++++++++++++++++++++++++-----------------
Msrc/kranewl/tree/node.cc | 10+++++-----
Msrc/kranewl/tree/output.cc | 36++++++++++++++++++------------------
Asrc/kranewl/tree/popup.cc | 13+++++++++++++
Dsrc/kranewl/tree/root.cc | 37-------------------------------------
Asrc/kranewl/tree/subsurface.cc | 13+++++++++++++
Msrc/kranewl/tree/view.cc | 22++++++++++++++++++++++
Asrc/kranewl/tree/xdg_view.cc | 13+++++++++++++
Asrc/kranewl/tree/xwayland_view.cc | 15+++++++++++++++
Msrc/kranewl/workspace.cc | 204++++++++++++++++++++++++++++++++++++++++----------------------------------------
32 files changed, 941 insertions(+), 438 deletions(-)

diff --git a/include/kranewl/common.hh b/include/kranewl/common.hh @@ -3,7 +3,6 @@ #include <cstddef> #include <cstdint> -typedef unsigned Pid; typedef std::uintptr_t Uid; typedef std::size_t Ident; typedef std::size_t Index; diff --git a/include/kranewl/geometry.hh b/include/kranewl/geometry.hh @@ -19,6 +19,17 @@ operator<<(std::ostream& os, Dim const& dim) return os << "(" << dim.w << "×" << dim.h << ")"; } +struct DDim final { + double w; + double h; +}; + +inline std::ostream& +operator<<(std::ostream& os, DDim const& dim) +{ + return os << "(" << dim.w << "×" << dim.h << ")"; +} + struct Pos final { int x; int y; @@ -87,6 +98,62 @@ operator-(Pos const& pos, Dim const& dim) }; } +struct DPos final { + double x; + double y; + + static DPos + from_center_of_dim(DDim dim) noexcept + { + return DPos { + dim.w / 2.0, + dim.h / 2.0 + }; + } +}; + +inline std::ostream& +operator<<(std::ostream& os, DPos const& pos) +{ + return os << "(" << pos.x << ", " << pos.y << ")"; +} + +inline DPos +operator+(DPos const& pos1, DPos const& pos2) +{ + return DPos{ + pos1.x + pos2.x, + pos1.y + pos2.y + }; +} + +inline DPos +operator-(DPos const& pos1, DPos const& pos2) +{ + return DPos{ + pos1.x - pos2.x, + pos1.y - pos2.y + }; +} + +inline DPos +operator+(DPos const& pos, DDim const& dim) +{ + return DPos{ + pos.x + dim.w, + pos.y + dim.h + }; +} + +inline DPos +operator-(DPos const& pos, DDim const& dim) +{ + return DPos{ + pos.x - dim.w, + pos.y - dim.h + }; +} + struct Padding final { int left; int right; @@ -131,6 +198,26 @@ operator<<(std::ostream& os, Region const& region) return os << "[" << region.pos << " " << region.dim << "]"; } +struct DRegion final { + DPos pos; + DDim dim; + + void apply_minimum_dim(DDim const&); + void apply_extents(Extents const&); + void remove_extents(Extents const&); + + bool contains(DPos) const; + bool contains(DRegion const&) const; + + Pos center() const; +}; + +inline std::ostream& +operator<<(std::ostream& os, DRegion const& region) +{ + return os << "[" << region.pos << " " << region.dim << "]"; +} + struct Distance final { int dx; int dy; @@ -141,3 +228,14 @@ operator<<(std::ostream& os, Distance const& dist) { return os << "𝛿(" << dist.dx << ", " << dist.dy << ")"; } + +struct DDistance final { + double dx; + double dy; +}; + +inline std::ostream& +operator<<(std::ostream& os, DDistance const& dist) +{ + return os << "𝛿(" << dist.dx << ", " << dist.dy << ")"; +} diff --git a/include/kranewl/input/seat.hh b/include/kranewl/input/seat.hh @@ -32,8 +32,10 @@ public: Seat(Server_ptr, Model_ptr, struct wlr_seat*, struct wlr_cursor*); ~Seat(); - static void handle_new_node(struct wl_listener*, void*); - static void handle_new_input(struct wl_listener*, void*); + Keyboard_ptr create_keyboard(struct wlr_input_device*); + void register_keyboard(Keyboard_ptr); + void unregister_keyboard(Keyboard_ptr); + static void handle_destroy(struct wl_listener*, void*); static void handle_cursor_motion(struct wl_listener*, void*); static void handle_cursor_motion_absolute(struct wl_listener*, void*); @@ -52,6 +54,7 @@ public: struct wlr_seat* mp_seat; struct wlr_cursor* mp_cursor; + struct wlr_xcursor_manager* mp_cursor_manager; CursorMode m_cursor_mode; std::vector<Keyboard_ptr> m_keyboards; @@ -65,8 +68,6 @@ public: struct wl_client* mp_exclusive_client; - struct wl_listener ml_new_node; - struct wl_listener ml_new_input; struct wl_listener ml_destroy; struct wl_listener ml_cursor_motion; struct wl_listener ml_cursor_motion_absolute; diff --git a/include/kranewl/layout.hh b/include/kranewl/layout.hh @@ -10,7 +10,7 @@ #include <unordered_map> class LayoutHandler final { - typedef std::deque<Client_ptr>::const_iterator client_iter; + typedef std::deque<View_ptr>::const_iterator view_iter; typedef std::vector<Placement>& placement_vector; public: @@ -104,7 +104,7 @@ public: LayoutHandler(); ~LayoutHandler(); - void arrange(Region, placement_vector, client_iter, client_iter) const; + void arrange(Region, placement_vector, view_iter, view_iter) const; LayoutKind kind() const; void set_kind(LayoutKind); @@ -147,22 +147,22 @@ private: Layout_ptr mp_layout; Layout_ptr mp_prev_layout; - void arrange_float(Region, placement_vector, client_iter, client_iter) const; - void arrange_frameless_float(Region, placement_vector, client_iter, client_iter) const; - void arrange_single_float(Region, placement_vector, client_iter, client_iter) const; - void arrange_frameless_single_float(Region, placement_vector, client_iter, client_iter) const; - void arrange_center(Region, placement_vector, client_iter, client_iter) const; - void arrange_monocle(Region, placement_vector, client_iter, client_iter) const; - void arrange_main_deck(Region, placement_vector, client_iter, client_iter) const; - void arrange_stack_deck(Region, placement_vector, client_iter, client_iter) const; - void arrange_double_deck(Region, placement_vector, client_iter, client_iter) const; - void arrange_paper(Region, placement_vector, client_iter, client_iter) const; - void arrange_compact_paper(Region, placement_vector, client_iter, client_iter) const; - void arrange_double_stack(Region, placement_vector, client_iter, client_iter) const; - void arrange_compact_double_stack(Region, placement_vector, client_iter, client_iter) const; - void arrange_horizontal_stack(Region, placement_vector, client_iter, client_iter) const; - void arrange_compact_horizontal_stack(Region, placement_vector, client_iter, client_iter) const; - void arrange_vertical_stack(Region, placement_vector, client_iter, client_iter) const; - void arrange_compact_vertical_stack(Region, placement_vector, client_iter, client_iter) const; + void arrange_float(Region, placement_vector, view_iter, view_iter) const; + void arrange_frameless_float(Region, placement_vector, view_iter, view_iter) const; + void arrange_single_float(Region, placement_vector, view_iter, view_iter) const; + void arrange_frameless_single_float(Region, placement_vector, view_iter, view_iter) const; + void arrange_center(Region, placement_vector, view_iter, view_iter) const; + void arrange_monocle(Region, placement_vector, view_iter, view_iter) const; + void arrange_main_deck(Region, placement_vector, view_iter, view_iter) const; + void arrange_stack_deck(Region, placement_vector, view_iter, view_iter) const; + void arrange_double_deck(Region, placement_vector, view_iter, view_iter) const; + void arrange_paper(Region, placement_vector, view_iter, view_iter) const; + void arrange_compact_paper(Region, placement_vector, view_iter, view_iter) const; + void arrange_double_stack(Region, placement_vector, view_iter, view_iter) const; + void arrange_compact_double_stack(Region, placement_vector, view_iter, view_iter) const; + void arrange_horizontal_stack(Region, placement_vector, view_iter, view_iter) const; + void arrange_compact_horizontal_stack(Region, placement_vector, view_iter, view_iter) const; + void arrange_vertical_stack(Region, placement_vector, view_iter, view_iter) const; + void arrange_compact_vertical_stack(Region, placement_vector, view_iter, view_iter) const; }; diff --git a/include/kranewl/model.hh b/include/kranewl/model.hh @@ -4,13 +4,17 @@ #include <kranewl/common.hh> #include <kranewl/cycle.hh> #include <kranewl/geometry.hh> -#include <kranewl/tree/client.hh> +#include <kranewl/tree/view.hh> #include <optional> #include <string> #include <unordered_map> #include <variant> +extern "C" { +#include <sys/types.h> +} + typedef class Output* Output_ptr; typedef class Context* Context_ptr; typedef class Workspace* Workspace_ptr; @@ -25,17 +29,13 @@ public: void register_server(Server_ptr); void exit(); - Keyboard_ptr create_keyboard(struct wlr_output*, struct wlr_scene_output*); - void register_keyboard(Keyboard_ptr); - void unregister_keyboard(Keyboard_ptr); - Output_ptr create_output(struct wlr_output*, struct wlr_scene_output*); void register_output(Output_ptr); void unregister_output(Output_ptr); - Client_ptr create_client(Surface); - void register_client(Client_ptr); - void unregister_client(Client_ptr); + View_ptr create_view(Surface); + void register_view(View_ptr); + void unregister_view(View_ptr); void spawn_external(std::string&&) const; @@ -46,7 +46,6 @@ private: bool m_running; Cycle<Output_ptr> m_outputs; - Cycle<Keyboard_ptr> m_keyboards; Cycle<Context_ptr> m_contexts; Cycle<Workspace_ptr> m_workspaces; @@ -59,14 +58,14 @@ private: Context_ptr mp_prev_context; Workspace_ptr mp_prev_workspace; - std::unordered_map<Uid, Client_ptr> m_client_map; - std::unordered_map<Pid, Client_ptr> m_pid_map; - std::unordered_map<Client_ptr, Region> m_fullscreen_map; + std::unordered_map<Uid, View_ptr> m_view_map; + std::unordered_map<pid_t, View_ptr> m_pid_map; + std::unordered_map<View_ptr, Region> m_fullscreen_map; - std::vector<Client_ptr> m_sticky_clients; - std::vector<Client_ptr> m_unmanaged_clients; + std::vector<View_ptr> m_sticky_views; + std::vector<View_ptr> m_unmanaged_views; - Client_ptr mp_focus; + View_ptr mp_focus; KeyBindings m_key_bindings; MouseBindings m_mouse_bindings; diff --git a/include/kranewl/placement.hh b/include/kranewl/placement.hh @@ -6,11 +6,11 @@ #include <cstdlib> #include <optional> -typedef class Client* Client_ptr; +typedef class View* View_ptr; struct PlacementTarget final { enum class TargetType { - Client, + View, Tab, Layout }; @@ -18,7 +18,7 @@ struct PlacementTarget final { TargetType type; union { - Client_ptr client; + View_ptr view; std::size_t tab; }; }; @@ -31,7 +31,7 @@ struct Placement final { }; PlacementMethod method; - Client_ptr client; + View_ptr view; Decoration decoration; std::optional<Region> region; }; diff --git a/include/kranewl/server.hh b/include/kranewl/server.hh @@ -1,7 +1,6 @@ #pragma once #include <kranewl/geometry.hh> -#include <kranewl/tree/root.hh> #include <kranewl/input/seat.hh> extern "C" { @@ -85,7 +84,6 @@ private: struct wlr_idle* mp_idle; struct wlr_server_decoration_manager* mp_server_decoration_manager; struct wlr_xdg_decoration_manager_v1* mp_xdg_decoration_manager; - struct wlr_xcursor_manager* mp_cursor_manager; struct wlr_pointer_constraints_v1* mp_pointer_constraints; struct wlr_relative_pointer_manager_v1* mp_relative_pointer_manager; struct wlr_virtual_pointer_manager_v1* mp_virtual_pointer_manager; diff --git a/include/kranewl/tree/client.hh b/include/kranewl/tree/client.hh @@ -20,6 +20,7 @@ typedef class Output* Output_ptr; typedef class Context* Context_ptr; typedef class Workspace* Workspace_ptr; typedef struct Client* Client_ptr; + typedef struct Client final { static constexpr Dim MIN_CLIENT_DIM = Dim{25, 10}; static constexpr Dim PREFERRED_INIT_CLIENT_DIM = Dim{480, 260}; diff --git a/include/kranewl/tree/container.hh b/include/kranewl/tree/container.hh @@ -1,3 +1,99 @@ #pragma once +#include <kranewl/common.hh> +#include <kranewl/geometry.hh> +#include <kranewl/decoration.hh> +#include <kranewl/tree/node.hh> +#include <vector> +#include <chrono> + +typedef struct View* View_ptr; + +typedef struct Container final : public Node { + enum class FullscreenMode { + None, + Workspace, + Context, + }; + + enum class BorderType { + None, + Pixel, + Normal, + Csd, + }; + + struct State { + double x, y; + double w, h; + + FullscreenMode fullscreen_mode; + bool focused; + + Workspace_ptr workspace; + Container_ptr parent; + std::vector<Container_ptr> children; + Container_ptr focused_inactive_child; + + BorderType border; + int border_thickness; + bool border_top; + bool border_bottom; + bool border_left; + bool border_right; + + double content_x, content_y; + double content_width, content_height; + }; + + Container(); + ~Container(); + + View_ptr m_view; + + State m_state; + State m_pending_state; + + DRegion m_free_region; + DRegion m_tile_region; + DRegion m_active_region; + DRegion m_previous_region; + DRegion m_inner_region; + + Decoration m_tile_decoration; + Decoration m_free_decoration; + Decoration m_active_decoration; + + bool m_mapped; + bool m_managed; + bool m_urgent; + bool m_floating; + bool m_fullscreen; + bool m_scratchpad; + bool m_contained; + bool m_invincible; + bool m_sticky; + bool m_iconifyable; + bool m_iconified; + bool m_disowned; + + std::string m_title; + std::string m_title_formatted; + + double m_saved_x, m_saved_y; + double m_saved_w, m_saved_h; + + float m_alpha; + uint32_t m_resize; + + std::vector<Output_ptr> m_outputs; + + std::chrono::time_point<std::chrono::steady_clock> m_last_focused; + std::chrono::time_point<std::chrono::steady_clock> m_managed_since; + + struct { + struct wl_signal destroy; + } m_events; + +}* Container_ptr; diff --git a/include/kranewl/tree/node.hh b/include/kranewl/tree/node.hh @@ -10,17 +10,17 @@ typedef class Root* Root_ptr; typedef class Output* Output_ptr; typedef class Context* Context_ptr; typedef class Workspace* Workspace_ptr; -typedef class Container* Container_ptr; - -enum class NodeType { - Root, - Output, - Context, - Workspace, - Container, -}; +typedef struct Container* Container_ptr; typedef struct Node { + enum class Type { + Root, + Output, + Context, + Workspace, + Container, + }; + protected: Node(Root_ptr); Node(Output_ptr); @@ -32,7 +32,7 @@ protected: public: Uid m_uid; - NodeType m_type; + Type m_type; union { Root_ptr m_root; Output_ptr m_output; diff --git a/include/kranewl/tree/output.hh b/include/kranewl/tree/output.hh @@ -26,9 +26,9 @@ public: static void handle_frame(struct wl_listener*, void*); static void handle_commit(struct wl_listener*, void*); - static void handle_destroy(struct wl_listener*, void*); static void handle_present(struct wl_listener*, void*); static void handle_mode(struct wl_listener*, void*); + static void handle_destroy(struct wl_listener*, void*); void set_context(Context_ptr context); Context_ptr context() const; @@ -55,9 +55,9 @@ public: struct wl_listener ml_frame; struct wl_listener ml_commit; - struct wl_listener ml_destroy; struct wl_listener ml_present; struct wl_listener ml_mode; + struct wl_listener ml_destroy; struct { struct wl_signal disable; diff --git a/include/kranewl/tree/popup.hh b/include/kranewl/tree/popup.hh @@ -0,0 +1,14 @@ +#pragma once + +#include <kranewl/tree/view.hh> + +struct PopupViewChild final : public ViewChild { + PopupViewChild(); + ~PopupViewChild(); + + struct wlr_xdg_popup* mp_wlr_xdg_popup; + + struct wl_listener ml_new_popup; + struct wl_listener ml_destroy; + +}; diff --git a/include/kranewl/tree/root.hh b/include/kranewl/tree/root.hh @@ -1,41 +0,0 @@ -#pragma once - -#include <kranewl/common.hh> -#include <kranewl/cycle.hh> -#include <kranewl/geometry.hh> -#include <kranewl/tree/node.hh> - -extern "C" { -#include <wayland-server-core.h> -} - -typedef class Server* Server_ptr; -typedef class Model* Model_ptr; - -typedef class Root final : public Node { -public: - Root(Server_ptr, Model_ptr, struct wlr_output_layout*); - ~Root(); - - static void handle_output_layout_change(struct wl_listener*, void*); - -public: - Server_ptr mp_server; - Model_ptr mp_model; - - struct wlr_output_layout* mp_output_layout; - - struct wl_listener ml_output_layout_change; - - struct { - struct wl_signal new_node; - } m_events; - - Region m_region; - - Cycle<Output_ptr> m_outputs; - Cycle<Container_ptr> m_scratchpad; - - Container_ptr mp_fullscreen_global; - -}* Root_ptr; diff --git a/include/kranewl/tree/subsurface.hh b/include/kranewl/tree/subsurface.hh @@ -0,0 +1,11 @@ +#pragma once + +#include <kranewl/tree/view.hh> + +struct SubsurfaceViewChild final : public ViewChild { + SubsurfaceViewChild(); + ~SubsurfaceViewChild(); + + struct wl_listener ml_destroy; + +}; diff --git a/include/kranewl/tree/view.hh b/include/kranewl/tree/view.hh @@ -1,23 +1,161 @@ #pragma once +#include <kranewl/common.hh> +#include <kranewl/decoration.hh> +#include <kranewl/geometry.hh> +#include <kranewl/tree/surface.hh> + +#include <vector> +#include <chrono> + extern "C" { -#include <wlr/backend.h> +#include <sys/types.h> +#include <wayland-server-core.h> } -class Server; -struct View { - struct wl_list link; +typedef class Server* Server_ptr; +typedef class Model* Model_ptr; +typedef class Seat* Seat_ptr; +typedef class Output* Output_ptr; +typedef class Context* Context_ptr; +typedef class Workspace* Workspace_ptr; +typedef struct XDGView* XDGView_ptr; +#if XWAYLAND +typedef struct XWaylandView* XWaylandView_ptr; +#endif +typedef struct View* View_ptr; + +typedef struct View { + static constexpr Dim MIN_VIEW_DIM = Dim{25, 10}; + static constexpr Dim PREFERRED_INIT_VIEW_DIM = Dim{480, 260}; + + enum class Type { + XDGShell, +#if XWAYLAND + XWayland, +#endif + }; + +protected: + View(XDGView_ptr); +#if XWAYLAND + View(XWaylandView_ptr); +#endif + +public: + ~View(); + + static bool + is_free(View_ptr view) + { + return (view->m_floating && (!view->m_fullscreen || view->m_contained)) + || !view->m_managed + || view->m_disowned; + } + + Uid m_uid; + Type m_type; + + Server_ptr mp_server; + Model_ptr mp_model; + Seat_ptr mp_seat; + + Output_ptr mp_output; + Context_ptr mp_context; + Workspace_ptr mp_workspace; + + struct wlr_scene_node* mp_scene; + struct wlr_scene_node* mp_scene_surface; + struct wlr_scene_rect* m_protrusions[4]; // top, bottom, left, right + + std::string m_title; + std::string m_title_formatted; + + float m_alpha; + uint32_t m_resize; + + pid_t m_pid; + + Decoration m_tile_decoration; + Decoration m_free_decoration; + Decoration m_active_decoration; + + Region m_preferred_region; + Region m_free_region; + Region m_tile_region; + Region m_active_region; + Region m_previous_region; + Region m_inner_region; + + bool m_focused; + bool m_mapped; + bool m_managed; + bool m_urgent; + bool m_floating; + bool m_fullscreen; + bool m_scratchpad; + bool m_contained; + bool m_invincible; + bool m_sticky; + bool m_iconifyable; + bool m_iconified; + bool m_disowned; + + std::chrono::time_point<std::chrono::steady_clock> m_last_focused; + std::chrono::time_point<std::chrono::steady_clock> m_managed_since; + + struct wlr_foreign_toplevel_handle_v1* foreign_toplevel; + + struct wl_listener ml_foreign_activate_request; + struct wl_listener ml_foreign_fullscreen_request; + struct wl_listener ml_foreign_close_request; + struct wl_listener ml_foreign_destroy; + struct wl_listener ml_surface_new_subsurface; + + struct { + struct wl_signal unmap; + } m_events; + +}* View_ptr; + +typedef struct ViewChild* ViewChild_ptr; +typedef struct SubsurfaceViewChild* SubsurfaceViewChild_ptr; +typedef struct PopupViewChild* PopupViewChild_ptr; + +typedef struct ViewChild { + enum class Type { + Subsurface, + Popup, + }; + +protected: + ViewChild(SubsurfaceViewChild_ptr); + ViewChild(PopupViewChild_ptr); + ~ViewChild(); + +public: + Uid m_uid; + Type m_type; + + View_ptr mp_view; + ViewChild_ptr mp_parent; + std::vector<ViewChild_ptr> m_children; + + struct wlr_scene_node* mp_scene; + struct wlr_scene_node* mp_scene_surface; + + bool m_mapped; - Server* server; + float m_alpha; + uint32_t m_resize; - struct wlr_xdg_surface* xdg_surface; - struct wlr_scene_node* scene_node; + pid_t m_pid; - struct wl_listener l_map; - struct wl_listener l_unmap; - struct wl_listener l_destroy; - struct wl_listener l_request_move; - struct wl_listener l_request_resize; + struct wl_listener ml_surface_commit; + struct wl_listener ml_surface_new_subsurface; + struct wl_listener ml_surface_map; + struct wl_listener ml_surface_unmap; + struct wl_listener ml_surface_destroy; + struct wl_listener ml_view_unmap; - int x, y; -}; +}* ViewChild_ptr; diff --git a/include/kranewl/tree/xdg_view.hh b/include/kranewl/tree/xdg_view.hh @@ -0,0 +1,20 @@ +#pragma once + +#include <kranewl/tree/view.hh> + +struct XDGView final : public View { + XDGView(); + ~XDGView(); + + struct wl_listener ml_commit; + struct wl_listener ml_request_move; + struct wl_listener ml_request_resize; + struct wl_listener ml_request_fullscreen; + struct wl_listener ml_set_title; + struct wl_listener ml_set_app_id; + struct wl_listener ml_new_popup; + struct wl_listener ml_map; + struct wl_listener ml_unmap; + struct wl_listener ml_destroy; + +}; diff --git a/include/kranewl/tree/xwayland_view.hh b/include/kranewl/tree/xwayland_view.hh @@ -0,0 +1,50 @@ +#pragma once + +#include <kranewl/tree/view.hh> + +#if XWAYLAND +struct XWaylandView final : public View { + XWaylandView(); + ~XWaylandView(); + + struct wl_listener ml_commit; + struct wl_listener ml_request_move; + struct wl_listener ml_request_resize; + struct wl_listener ml_request_maximize; + struct wl_listener ml_request_minimize; + struct wl_listener ml_request_configure; + struct wl_listener ml_request_fullscreen; + struct wl_listener ml_request_activate; + struct wl_listener ml_set_title; + struct wl_listener ml_set_class; + struct wl_listener ml_set_role; + struct wl_listener ml_set_window_type; + struct wl_listener ml_set_hints; + struct wl_listener ml_set_decorations; + struct wl_listener ml_map; + struct wl_listener ml_unmap; + struct wl_listener ml_destroy; + struct wl_listener ml_override_redirect; + +}; + +struct XWaylandUnmanaged final { + XWaylandUnmanaged(); + ~XWaylandUnmanaged(); + + Pos m_pos; + + struct wlr_xwayland_surface* m_wlr_xwayland_surface; + + struct wl_listener ml_request_activate; + struct wl_listener ml_request_configure; + struct wl_listener ml_request_fullscreen; + struct wl_listener ml_commit; + struct wl_listener ml_set_geometry; + struct wl_listener ml_map; + struct wl_listener ml_unmap; + struct wl_listener ml_destroy; + struct wl_listener ml_override_redirect; + +}; +#endif diff --git a/include/kranewl/workspace.hh b/include/kranewl/workspace.hh @@ -7,7 +7,7 @@ #include <kranewl/placement.hh> #include <kranewl/util.hh> -typedef class Client* Client_ptr; +typedef class View* View_ptr; typedef class Context* Context_ptr; typedef class Workspace final { public: @@ -17,14 +17,15 @@ public: m_layout_handler({}), mp_context(context), mp_active(nullptr), - m_clients({}, true), - m_icons({}, true), - m_disowned({}, true), + m_views({}, true), + m_free_views({}, true), + m_iconified_views({}, true), + m_disowned_views({}, true), m_focus_follows_mouse(false) {} bool empty() const; - bool contains(Client_ptr) const; + bool contains(View_ptr) const; bool focus_follows_mouse() const; void set_focus_follows_mouse(bool); @@ -45,13 +46,13 @@ public: Index index() const; std::string const& name() const; std::string identifier() const; - Client_ptr active() const; + View_ptr active() const; - Cycle<Client_ptr> const& clients() const; - std::vector<Client_ptr> stack_after_focus() const; + Cycle<View_ptr> const& views() const; + std::vector<View_ptr> stack_after_focus() const; - Client_ptr next_client() const; - Client_ptr prev_client() const; + View_ptr next_view() const; + View_ptr prev_view() const; void cycle(Direction); void drag(Direction); @@ -60,22 +61,22 @@ public: void shuffle_main(Direction); void shuffle_stack(Direction); - void activate_client(Client_ptr); + void activate_view(View_ptr); - void add_client(Client_ptr); - void remove_client(Client_ptr); - void replace_client(Client_ptr, Client_ptr); + void add_view(View_ptr); + void remove_view(View_ptr); + void replace_view(View_ptr, View_ptr); - void client_to_icon(Client_ptr); - void icon_to_client(Client_ptr); - void add_icon(Client_ptr); - void remove_icon(Client_ptr); - std::optional<Client_ptr> pop_icon(); + void view_to_icon(View_ptr); + void icon_to_view(View_ptr); + void add_icon(View_ptr); + void remove_icon(View_ptr); + std::optional<View_ptr> pop_icon(); - void client_to_disowned(Client_ptr); - void disowned_to_client(Client_ptr); - void add_disowned(Client_ptr); - void remove_disowned(Client_ptr); + void view_to_disowned(View_ptr); + void disowned_to_view(View_ptr); + void add_disowned(View_ptr); + void remove_disowned(View_ptr); void toggle_layout_data(); void cycle_layout_data(Direction); @@ -97,52 +98,52 @@ public: void set_layout(LayoutHandler::LayoutKind); std::vector<Placement> arrange(Region) const; - std::deque<Client_ptr>::iterator + std::deque<View_ptr>::iterator begin() { - return m_clients.begin(); + return m_views.begin(); } - std::deque<Client_ptr>::const_iterator + std::deque<View_ptr>::const_iterator begin() const { - return m_clients.begin(); + return m_views.begin(); } - std::deque<Client_ptr>::const_iterator + std::deque<View_ptr>::const_iterator cbegin() const { - return m_clients.cbegin(); + return m_views.cbegin(); } - std::deque<Client_ptr>::iterator + std::deque<View_ptr>::iterator end() { - return m_clients.end(); + return m_views.end(); } - std::deque<Client_ptr>::const_iterator + std::deque<View_ptr>::const_iterator end() const { - return m_clients.end(); + return m_views.end(); } - std::deque<Client_ptr>::const_iterator + std::deque<View_ptr>::const_iterator cend() const { - return m_clients.cend(); + return m_views.cend(); } - Client_ptr + View_ptr operator[](Index i) { - return m_clients[i]; + return m_views[i]; } - Client_ptr + View_ptr operator[](Index i) const { - return m_clients[i]; + return m_views[i]; } private: @@ -153,10 +154,11 @@ private: Context_ptr mp_context; - Client_ptr mp_active; - Cycle<Client_ptr> m_clients; - Cycle<Client_ptr> m_icons; - Cycle<Client_ptr> m_disowned; + View_ptr mp_active; + Cycle<View_ptr> m_views; + Cycle<View_ptr> m_free_views; + Cycle<View_ptr> m_iconified_views; + Cycle<View_ptr> m_disowned_views; bool m_focus_follows_mouse; diff --git a/include/version.hh b/include/version.hh @@ -1 +1 @@ -#define VERSION "master/ace8d70+" -\ No newline at end of file +#define VERSION "master/78d93d1+" +\ No newline at end of file diff --git a/src/kranewl/input/seat.cc b/src/kranewl/input/seat.cc @@ -1,10 +1,13 @@ #include <trace.hh> +#include <kranewl/input/keyboard.hh> #include <kranewl/input/seat.hh> +#include <kranewl/util.hh> extern "C" { -#include <wlr/types/wlr_seat.h> #include <wlr/types/wlr_cursor.h> +#include <wlr/types/wlr_seat.h> +#include <wlr/types/wlr_xcursor_manager.h> } Seat::Seat( @@ -17,8 +20,7 @@ Seat::Seat( mp_model(model), mp_seat(seat), mp_cursor(cursor), - ml_new_node({ .notify = Seat::handle_new_node }), - ml_new_input({ .notify = Seat::handle_new_input }), + mp_cursor_manager(wlr_xcursor_manager_create(NULL, 24)), ml_destroy({ .notify = Seat::handle_destroy }), ml_cursor_motion({ .notify = Seat::handle_cursor_motion }), ml_cursor_motion_absolute({ .notify = Seat::handle_cursor_motion_absolute }), @@ -33,8 +35,8 @@ Seat::Seat( { TRACE(); - /* wl_signal_add(&seat->events.__, &ml_new_node); */ - /* wl_signal_add(&seat->events.new_input, &ml_new_input); */ + wlr_xcursor_manager_load(mp_cursor_manager, 1); + wl_signal_add(&seat->events.destroy, &ml_destroy); wl_signal_add(&cursor->events.motion, &ml_cursor_motion); wl_signal_add(&cursor->events.motion_absolute, &ml_cursor_motion_absolute); @@ -54,18 +56,65 @@ Seat::~Seat() } -void -Seat::handle_new_node(struct wl_listener*, void*) +static void +process_cursor_move(Seat_ptr seat, uint32_t time) { - TRACE(); } +static void +process_cursor_resize(Seat_ptr seat, uint32_t time) +{ + +} + +static void +process_cursor_motion(Seat_ptr seat, uint32_t time) +{ + switch (seat->m_cursor_mode) { + case Seat::CursorMode::Move: process_cursor_move(seat, time); return; + case Seat::CursorMode::Resize: process_cursor_resize(seat, time); return; + case Seat::CursorMode::Passthrough: // fallthrough + default: break; + } + + double sx, sy; + struct wlr_surface* surface = NULL; + // TODO: get client under cursor + + if (true /* no client under cursor? */) { + wlr_xcursor_manager_set_cursor_image( + seat->mp_cursor_manager, + "left_ptr", + seat->mp_cursor + ); + } + + if (surface) { + wlr_seat_pointer_notify_enter(seat->mp_seat, surface, sx, sy); + wlr_seat_pointer_notify_motion(seat->mp_seat, time, sx, sy); + } else + wlr_seat_pointer_clear_focus(seat->mp_seat); +} + +Keyboard_ptr +Seat::create_keyboard(struct wlr_input_device* device) +{ + Keyboard_ptr keyboard = new Keyboard(mp_server, this, device); + register_keyboard(keyboard); + return keyboard; +} + void -Seat::handle_new_input(struct wl_listener*, void*) +Seat::register_keyboard(Keyboard_ptr keyboard) { - TRACE(); + m_keyboards.push_back(keyboard); +} +void +Seat::unregister_keyboard(Keyboard_ptr keyboard) +{ + Util::erase_remove(m_keyboards, keyboard); } void @@ -76,17 +125,29 @@ Seat::handle_destroy(struct wl_listener*, void*) } void -Seat::handle_cursor_motion(struct wl_listener*, void*) +Seat::handle_cursor_motion(struct wl_listener* listener, void* data) { TRACE(); + Seat_ptr seat = wl_container_of(listener, seat, ml_cursor_motion); + struct wlr_event_pointer_motion* event + = reinterpret_cast<struct wlr_event_pointer_motion*>(data); + + wlr_cursor_move(seat->mp_cursor, event->device, event->delta_x, event->delta_y); + process_cursor_motion(seat, event->time_msec); } void -Seat::handle_cursor_motion_absolute(struct wl_listener*, void*) +Seat::handle_cursor_motion_absolute(struct wl_listener* listener, void* data) { TRACE(); + Seat_ptr seat = wl_container_of(listener, seat, ml_cursor_motion_absolute); + struct wlr_event_pointer_motion_absolute* event + = reinterpret_cast<struct wlr_event_pointer_motion_absolute*>(data); + + wlr_cursor_warp_absolute(seat->mp_cursor, event->device, event->x, event->y); + process_cursor_motion(seat, event->time_msec); } void @@ -104,10 +165,12 @@ Seat::handle_cursor_axis(struct wl_listener*, void*) } void -Seat::handle_cursor_frame(struct wl_listener*, void*) +Seat::handle_cursor_frame(struct wl_listener* listener, void*) { TRACE(); + Seat_ptr seat = wl_container_of(listener, seat, ml_cursor_frame); + wlr_seat_pointer_notify_frame(seat->mp_seat); } void diff --git a/src/kranewl/layout.cc b/src/kranewl/layout.cc @@ -1,7 +1,7 @@ #include <kranewl/layout.hh> #include <kranewl/cycle.t.hh> -#include <kranewl/tree/client.hh> +#include <kranewl/tree/view.hh> #include <kranewl/util.hh> #include <spdlog/spdlog.h> @@ -68,8 +68,8 @@ void LayoutHandler::arrange( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { if (mp_layout->config.margin) { @@ -177,13 +177,13 @@ LayoutHandler::arrange( placements.begin(), placements.end(), [data](Placement& placement) { - if (placement.region && !Client::is_free(placement.client)) { + if (placement.region && !View::is_free(placement.view)) { placement.region->pos.x += data->gap_size; placement.region->pos.y += data->gap_size; placement.region->dim.w -= 2 * data->gap_size; placement.region->dim.h -= 2 * data->gap_size; - placement.region->apply_minimum_dim(Client::MIN_CLIENT_DIM); + placement.region->apply_minimum_dim(View::MIN_VIEW_DIM); } } ); @@ -499,20 +499,20 @@ void LayoutHandler::arrange_float( Region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { std::transform( begin, end, std::back_inserter(placements), - [this](Client_ptr client) -> Placement { + [this](View_ptr view) -> Placement { return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, - client->m_free_region + view->m_free_region }; } ); @@ -522,8 +522,8 @@ void LayoutHandler::arrange_frameless_float( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { arrange_float(screen_region, placements, begin, end); @@ -533,20 +533,20 @@ void LayoutHandler::arrange_single_float( Region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { std::transform( begin, end, std::back_inserter(placements), - [this](Client_ptr client) -> Placement { + [this](View_ptr view) -> Placement { return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, - client->m_focused ? std::optional(client->m_free_region) : std::nullopt + view->m_focused ? std::optional(view->m_free_region) : std::nullopt }; } ); @@ -556,8 +556,8 @@ void LayoutHandler::arrange_frameless_single_float( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { arrange_single_float(screen_region, placements, begin, end); @@ -567,8 +567,8 @@ void LayoutHandler::arrange_center( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { const Layout::LayoutData_ptr data = *mp_layout->data.active_element(); @@ -582,7 +582,7 @@ LayoutHandler::arrange_center( begin, end, std::back_inserter(placements), - [=,this](Client_ptr client) -> Placement { + [=,this](View_ptr view) -> Placement { Region region = screen_region; int w = static_cast<int>(static_cast<float>(region.dim.w) * w_ratio); @@ -598,7 +598,7 @@ LayoutHandler::arrange_center( return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, region }; @@ -610,18 +610,18 @@ void LayoutHandler::arrange_monocle( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { std::transform( begin, end, std::back_inserter(placements), - [=,this](Client_ptr client) { + [=,this](View_ptr view) { return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, screen_region }; @@ -633,8 +633,8 @@ void LayoutHandler::arrange_main_deck( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { const Layout::LayoutData_ptr data = *mp_layout->data.active_element(); @@ -680,12 +680,12 @@ LayoutHandler::arrange_main_deck( begin, end, std::back_inserter(placements), - [=,this,&i](Client_ptr client) -> Placement { + [=,this,&i](View_ptr view) -> Placement { if (i < data->main_count) { ++i; return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, Region { Pos { @@ -701,7 +701,7 @@ LayoutHandler::arrange_main_deck( } else { return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, Region { Pos { @@ -724,8 +724,8 @@ void LayoutHandler::arrange_stack_deck( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { const Layout::LayoutData_ptr data = *mp_layout->data.active_element(); @@ -769,11 +769,11 @@ LayoutHandler::arrange_stack_deck( begin, end, std::back_inserter(placements), - [=,this,&i](Client_ptr client) -> Placement { + [=,this,&i](View_ptr view) -> Placement { if (i < data->main_count) { return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, Region { Pos { @@ -791,7 +791,7 @@ LayoutHandler::arrange_stack_deck( ++i; return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, Region { Pos { @@ -813,8 +813,8 @@ void LayoutHandler::arrange_double_deck( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { const Layout::LayoutData_ptr data = *mp_layout->data.active_element(); @@ -858,11 +858,11 @@ LayoutHandler::arrange_double_deck( begin, end, std::back_inserter(placements), - [=,this,&i](Client_ptr client) -> Placement { + [=,this,&i](View_ptr view) -> Placement { if (i++ < data->main_count) { return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, Region { Pos { @@ -878,7 +878,7 @@ LayoutHandler::arrange_double_deck( } else { return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, Region { Pos { @@ -900,8 +900,8 @@ void LayoutHandler::arrange_paper( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { static const float MIN_W_RATIO = 0.5; @@ -934,7 +934,7 @@ LayoutHandler::arrange_paper( const auto last_active = std::max_element( begin, end, - [&contains_active](const Client_ptr lhs, const Client_ptr rhs) { + [&contains_active](const View_ptr lhs, const View_ptr rhs) { if (lhs->m_focused) { contains_active = true; return false; @@ -954,15 +954,15 @@ LayoutHandler::arrange_paper( begin, end, std::back_inserter(placements), - [=,this,&after_active,&i](Client_ptr client) -> Placement { + [=,this,&after_active,&i](View_ptr view) -> Placement { int x = screen_region.pos.x + static_cast<int>(i++ * w); - if ((!contains_active && *last_active == client) || client->m_focused) { + if ((!contains_active && *last_active == view) || view->m_focused) { after_active = true; return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, Region { Pos { @@ -981,7 +981,7 @@ LayoutHandler::arrange_paper( return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, Region { Pos { @@ -1003,8 +1003,8 @@ void LayoutHandler::arrange_compact_paper( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { arrange_paper(screen_region, placements, begin, end); @@ -1014,8 +1014,8 @@ void LayoutHandler::arrange_double_stack( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { const Layout::LayoutData_ptr data = *mp_layout->data.active_element(); @@ -1059,11 +1059,11 @@ LayoutHandler::arrange_double_stack( begin, end, std::back_inserter(placements), - [=,this,&i](Client_ptr client) -> Placement { + [=,this,&i](View_ptr view) -> Placement { if (i < data->main_count) { return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, Region { Pos { @@ -1080,7 +1080,7 @@ LayoutHandler::arrange_double_stack( } else { return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, Region { Pos { @@ -1103,8 +1103,8 @@ void LayoutHandler::arrange_compact_double_stack( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { arrange_double_stack(screen_region, placements, begin, end); @@ -1114,8 +1114,8 @@ void LayoutHandler::arrange_horizontal_stack( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { int n = static_cast<int>(end - begin); @@ -1138,10 +1138,10 @@ LayoutHandler::arrange_horizontal_stack( begin, end, std::back_inserter(placements), - [=,this,&i](Client_ptr client) -> Placement { + [=,this,&i](View_ptr view) -> Placement { return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, Region { Pos { @@ -1162,8 +1162,8 @@ void LayoutHandler::arrange_compact_horizontal_stack( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { arrange_horizontal_stack(screen_region, placements, begin, end); @@ -1173,8 +1173,8 @@ void LayoutHandler::arrange_vertical_stack( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { int n = static_cast<int>(end - begin); @@ -1197,10 +1197,10 @@ LayoutHandler::arrange_vertical_stack( begin, end, std::back_inserter(placements), - [=,this,&i](Client_ptr client) -> Placement { + [=,this,&i](View_ptr view) -> Placement { return Placement { mp_layout->config.method, - client, + view, mp_layout->config.decoration, Region { Pos { @@ -1221,8 +1221,8 @@ void LayoutHandler::arrange_compact_vertical_stack( Region screen_region, placement_vector placements, - client_iter begin, - client_iter end + view_iter begin, + view_iter end ) const { arrange_vertical_stack(screen_region, placements, begin, end); diff --git a/src/kranewl/model.cc b/src/kranewl/model.cc @@ -8,7 +8,6 @@ #include <kranewl/context.hh> #include <kranewl/cycle.t.hh> #include <kranewl/exec.hh> -#include <kranewl/input/keyboard.hh> #include <kranewl/input/mouse.hh> #include <kranewl/server.hh> #include <kranewl/tree/output.hh> @@ -23,7 +22,6 @@ Model::Model( : m_config{config}, m_running{true}, m_outputs{{}, true}, - m_keyboards{{}, false}, m_contexts{{}, true}, m_workspaces{{}, true}, mp_output{nullptr}, @@ -33,11 +31,11 @@ Model::Model( mp_prev_output{nullptr}, mp_prev_context{nullptr}, mp_prev_workspace{nullptr}, - m_client_map{}, + m_view_map{}, m_pid_map{}, m_fullscreen_map{}, - m_sticky_clients{}, - m_unmanaged_clients{}, + m_sticky_views{}, + m_unmanaged_views{}, mp_focus(nullptr), m_key_bindings{}, m_mouse_bindings{} @@ -132,29 +130,29 @@ Model::unregister_output(Output_ptr output) delete output; } -Client_ptr -Model::create_client(Surface surface) +View_ptr +Model::create_view(Surface surface) { - Client_ptr client = new Client( - mp_server, - surface, - mp_output, - mp_context, - mp_workspace - ); + /* View_ptr view = new View( */ + /* mp_server, */ + /* surface, */ + /* mp_output, */ + /* mp_context, */ + /* mp_workspace */ + /* ); */ - register_client(client); + /* register_view(view); */ - return client; + /* return view; */ } void -Model::register_client(Client_ptr client) +Model::register_view(View_ptr view) { } void -Model::unregister_client(Client_ptr client) +Model::unregister_view(View_ptr view) { - delete client; + delete view; } diff --git a/src/kranewl/server.cc b/src/kranewl/server.cc @@ -51,7 +51,6 @@ extern "C" { #include <wlr/types/wlr_server_decoration.h> #include <wlr/types/wlr_virtual_keyboard_v1.h> #include <wlr/types/wlr_virtual_pointer_v1.h> -#include <wlr/types/wlr_xcursor_manager.h> #include <wlr/types/wlr_xdg_activation_v1.h> #include <wlr/types/wlr_xdg_decoration_v1.h> #include <wlr/types/wlr_xdg_output_v1.h> @@ -83,7 +82,6 @@ Server::Server(Model_ptr model) mp_renderer([](struct wl_display* display, struct wlr_backend* backend) { struct wlr_renderer* renderer = wlr_renderer_autocreate(backend); wlr_renderer_init_wl_display(renderer, display); - return renderer; }(mp_display, mp_backend)), mp_allocator(wlr_allocator_autocreate(mp_backend, mp_renderer)), @@ -91,7 +89,7 @@ Server::Server(Model_ptr model) mp_data_device_manager(wlr_data_device_manager_create(mp_display)), mp_output_layout([this]() { struct wlr_output_layout* output_layout = wlr_output_layout_create(); - /* wlr_xdg_output_manager_v1_create(mp_display, output_layout); */ + wlr_xdg_output_manager_v1_create(mp_display, output_layout); return output_layout; }()), mp_scene([this]() { @@ -99,16 +97,6 @@ Server::Server(Model_ptr model) wlr_scene_attach_output_layout(scene, mp_output_layout); return scene; }()), - /* m_root([this](struct wl_display* display) { */ - /* struct wlr_output_layout* wlr_output_layout = wlr_output_layout_create(); */ - /* wlr_xdg_output_manager_v1_create(display, wlr_output_layout); */ - - /* return Root( */ - /* this, */ - /* mp_model, */ - /* wlr_output_layout */ - /* ); */ - /* }(mp_display)), */ m_seat([this]() { struct wlr_cursor* cursor = wlr_cursor_create(); wlr_cursor_attach_output_layout(cursor, mp_output_layout); @@ -119,7 +107,6 @@ Server::Server(Model_ptr model) #endif mp_layer_shell(wlr_layer_shell_v1_create(mp_display)), mp_xdg_shell(wlr_xdg_shell_create(mp_display)), - mp_cursor_manager(wlr_xcursor_manager_create(NULL, 24)), mp_presentation(wlr_presentation_create(mp_display, mp_backend)), mp_idle(wlr_idle_create(mp_display)), mp_idle_inhibit_manager(wlr_idle_inhibit_v1_create(mp_display)), @@ -133,7 +120,7 @@ Server::Server(Model_ptr model) mp_virtual_pointer_manager(wlr_virtual_pointer_manager_v1_create(mp_display)), mp_virtual_keyboard_manager(wlr_virtual_keyboard_manager_v1_create(mp_display)), ml_new_output({ .notify = Server::handle_new_output }), - ml_output_layout_change({ .notify = Root::handle_output_layout_change }), + ml_output_layout_change({ .notify = Server::handle_output_layout_change }), ml_output_manager_apply({ .notify = Server::handle_output_manager_apply }), ml_output_manager_test({ .notify = Server::handle_output_manager_test }), ml_new_xdg_surface({ .notify = Server::handle_new_xdg_surface }), @@ -166,7 +153,6 @@ Server::Server(Model_ptr model) wlr_gamma_control_manager_v1_create(mp_display); wlr_primary_selection_v1_device_manager_create(mp_display); - wlr_xcursor_manager_load(mp_cursor_manager, 1); wlr_server_decoration_manager_set_default_mode( mp_server_decoration_manager, WLR_SERVER_DECORATION_MANAGER_MODE_SERVER @@ -305,10 +291,41 @@ Server::handle_xdg_activation(struct wl_listener*, void*) } void -Server::handle_new_input(struct wl_listener*, void*) +Server::handle_new_input(struct wl_listener* listener, void* data) { TRACE(); + Server_ptr server = wl_container_of(listener, server, ml_new_input); + struct wlr_input_device* device + = reinterpret_cast<struct wlr_input_device*>(data); + + switch (device->type) { + case WLR_INPUT_DEVICE_KEYBOARD: + { + Keyboard_ptr keyboard = server->m_seat.create_keyboard(device); + + struct xkb_context* context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + struct xkb_keymap* keymap + = xkb_keymap_new_from_names(context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS); + + wlr_keyboard_set_keymap(device->keyboard, keymap); + xkb_keymap_unref(keymap); + xkb_context_unref(context); + wlr_keyboard_set_repeat_info(device->keyboard, 200, 100); + wlr_seat_set_keyboard(server->m_seat.mp_seat, device); + } + break; + case WLR_INPUT_DEVICE_POINTER: + wlr_cursor_attach_input_device(server->m_seat.mp_cursor, device); + break; + default: break; + } + + uint32_t caps = WL_SEAT_CAPABILITY_POINTER; + if (!server->m_seat.m_keyboards.empty()) + caps |= WL_SEAT_CAPABILITY_KEYBOARD; + + wlr_seat_set_capabilities(server->m_seat.mp_seat, caps); } void diff --git a/src/kranewl/tree/node.cc b/src/kranewl/tree/node.cc @@ -2,7 +2,7 @@ Node::Node(Root_ptr root) : m_uid(reinterpret_cast<Uid>(root)), - m_type(NodeType::Root), + m_type(Type::Root), m_root(root), m_destroying(false), m_dirty(false), @@ -11,7 +11,7 @@ Node::Node(Root_ptr root) Node::Node(Output_ptr output) : m_uid(reinterpret_cast<Uid>(output)), - m_type(NodeType::Output), + m_type(Type::Output), m_output(output), m_destroying(false), m_dirty(false), @@ -20,7 +20,7 @@ Node::Node(Output_ptr output) Node::Node(Context_ptr context) : m_uid(reinterpret_cast<Uid>(context)), - m_type(NodeType::Context), + m_type(Type::Context), m_context(context), m_destroying(false), m_dirty(false), @@ -29,7 +29,7 @@ Node::Node(Context_ptr context) Node::Node(Workspace_ptr workspace) : m_uid(reinterpret_cast<Uid>(workspace)), - m_type(NodeType::Workspace), + m_type(Type::Workspace), m_workspace(workspace), m_destroying(false), m_dirty(false), @@ -38,7 +38,7 @@ Node::Node(Workspace_ptr workspace) Node::Node(Container_ptr container) : m_uid(reinterpret_cast<Uid>(container)), - m_type(NodeType::Container), + m_type(Type::Container), m_container(container), m_destroying(false), m_dirty(false), diff --git a/src/kranewl/tree/output.cc b/src/kranewl/tree/output.cc @@ -32,18 +32,18 @@ Output::Output( mp_wlr_scene_output(wlr_scene_output), m_subpixel(wlr_output->subpixel), ml_frame({ .notify = Output::handle_frame }), - ml_destroy({ .notify = Output::handle_destroy }), + ml_commit({ .notify = Output::handle_commit }), ml_present({ .notify = Output::handle_present }), ml_mode({ .notify = Output::handle_mode }), - ml_commit({ .notify = Output::handle_commit }) + ml_destroy({ .notify = Output::handle_destroy }) { TRACE(); - wl_signal_add(&mp_wlr_output->events.destroy, &ml_destroy); wl_signal_add(&mp_wlr_output->events.frame, &ml_frame); + wl_signal_add(&mp_wlr_output->events.commit, &ml_commit); wl_signal_add(&mp_wlr_output->events.present, &ml_present); wl_signal_add(&mp_wlr_output->events.mode, &ml_mode); - wl_signal_add(&mp_wlr_output->events.commit, &ml_commit); + wl_signal_add(&mp_wlr_output->events.destroy, &ml_destroy); wl_signal_init(&m_events.disable); } @@ -75,6 +75,20 @@ Output::handle_commit(struct wl_listener*, void*) } void +Output::handle_present(struct wl_listener*, void*) +{ + TRACE(); + +} + +void +Output::handle_mode(struct wl_listener*, void*) +{ + TRACE(); + +} + +void Output::handle_destroy(struct wl_listener*, void* data) { TRACE(); @@ -95,20 +109,6 @@ Output::handle_destroy(struct wl_listener*, void* data) } void -Output::handle_present(struct wl_listener*, void*) -{ - TRACE(); - -} - -void -Output::handle_mode(struct wl_listener*, void*) -{ - TRACE(); - -} - -void Output::set_context(Context_ptr context) { TRACE(); diff --git a/src/kranewl/tree/popup.cc b/src/kranewl/tree/popup.cc @@ -0,0 +1,13 @@ +#include <kranewl/tree/view.hh> +#include <kranewl/tree/popup.hh> + +PopupViewChild::PopupViewChild() + : ViewChild(this) +{ + +} + +PopupViewChild::~PopupViewChild() +{ + +} diff --git a/src/kranewl/tree/root.cc b/src/kranewl/tree/root.cc @@ -1,37 +0,0 @@ -#include <trace.hh> - -#include <kranewl/tree/root.hh> -#include <kranewl/cycle.t.hh> - -extern "C" { -#include <wlr/types/wlr_output_layout.h> -} - -Root::Root( - Server_ptr server, - Model_ptr model, - struct wlr_output_layout* wlr_output_layout -) - : Node(this), - mp_server(server), - mp_model(model), - mp_output_layout(wlr_output_layout), - ml_output_layout_change({ .notify = Root::handle_output_layout_change }), - m_outputs({}, true), - m_scratchpad({}, true) -{ - TRACE(); - - wl_signal_add(&mp_output_layout->events.change, &ml_output_layout_change); - wl_signal_init(&m_events.new_node); -} - -Root::~Root() -{} - -void -Root::handle_output_layout_change(struct wl_listener*, void*) -{ - TRACE(); - -} diff --git a/src/kranewl/tree/subsurface.cc b/src/kranewl/tree/subsurface.cc @@ -0,0 +1,13 @@ +#include <kranewl/tree/view.hh> +#include <kranewl/tree/subsurface.hh> + +SubsurfaceViewChild::SubsurfaceViewChild() + : ViewChild(this) +{ + +} + +SubsurfaceViewChild::~SubsurfaceViewChild() +{ + +} diff --git a/src/kranewl/tree/view.cc b/src/kranewl/tree/view.cc @@ -1,3 +1,25 @@ #include <kranewl/tree/view.hh> +View::View(XDGView_ptr) + : m_type(Type::XDGShell) +{} +#if XWAYLAND +View::View(XWaylandView_ptr) + : m_type(Type::XWayland) +{} +#endif + +View::~View() +{} + +ViewChild::ViewChild(SubsurfaceViewChild_ptr) + : m_type(Type::Subsurface) +{} + +ViewChild::ViewChild(PopupViewChild_ptr) + : m_type(Type::Popup) +{} + +ViewChild::~ViewChild() +{} diff --git a/src/kranewl/tree/xdg_view.cc b/src/kranewl/tree/xdg_view.cc @@ -0,0 +1,13 @@ +#include <kranewl/tree/view.hh> +#include <kranewl/tree/xdg_view.hh> + +XDGView::XDGView() + : View(this) +{ + +} + +XDGView::~XDGView() +{ + +} diff --git a/src/kranewl/tree/xwayland_view.cc b/src/kranewl/tree/xwayland_view.cc @@ -0,0 +1,15 @@ +#include <kranewl/tree/view.hh> +#include <kranewl/tree/xwayland_view.hh> + +#if XWAYLAND +XWaylandView::XWaylandView() + : View(this) +{ + +} + +XWaylandView::~XWaylandView() +{ + +} +#endif diff --git a/src/kranewl/workspace.cc b/src/kranewl/workspace.cc @@ -2,7 +2,7 @@ #include <kranewl/context.hh> #include <kranewl/cycle.t.hh> -#include <kranewl/tree/client.hh> +#include <kranewl/tree/view.hh> #include <kranewl/util.hh> #include <algorithm> @@ -11,13 +11,13 @@ bool Workspace::empty() const { - return m_clients.empty(); + return m_views.empty(); } bool -Workspace::contains(Client_ptr client) const +Workspace::contains(View_ptr view) const { - return m_clients.contains(client); + return m_views.contains(view); } bool @@ -71,13 +71,13 @@ Workspace::layout_wraps() const std::size_t Workspace::size() const { - return m_clients.size(); + return m_views.size(); } std::size_t Workspace::length() const { - return m_clients.length(); + return m_views.length(); } int @@ -119,23 +119,23 @@ Workspace::identifier() const + std::to_string(m_index); } -Client_ptr +View_ptr Workspace::active() const { return mp_active; } -Cycle<Client_ptr> const& -Workspace::clients() const +Cycle<View_ptr> const& +Workspace::views() const { - return m_clients; + return m_views; } -std::vector<Client_ptr> +std::vector<View_ptr> Workspace::stack_after_focus() const { - std::vector<Client_ptr> stack = m_clients.stack(); + std::vector<View_ptr> stack = m_views.stack(); if (mp_active) { Util::erase_remove(stack, mp_active); @@ -145,26 +145,26 @@ Workspace::stack_after_focus() const return stack; } -Client_ptr -Workspace::next_client() const +View_ptr +Workspace::next_view() const { - std::optional<Client_ptr> client - = m_clients.next_element(Direction::Forward); + std::optional<View_ptr> view + = m_views.next_element(Direction::Forward); - if (client != mp_active) - return *client; + if (view != mp_active) + return *view; return nullptr; } -Client_ptr -Workspace::prev_client() const +View_ptr +Workspace::prev_view() const { - std::optional<Client_ptr> client - = m_clients.next_element(Direction::Backward); + std::optional<View_ptr> view + = m_views.next_element(Direction::Backward); - if (client != mp_active) - return *client; + if (view != mp_active) + return *view; return nullptr; } @@ -175,22 +175,22 @@ Workspace::cycle(Direction direction) switch (direction) { case Direction::Forward: { - if (!layout_wraps() && m_clients.active_index() == m_clients.last_index()) + if (!layout_wraps() && m_views.active_index() == m_views.last_index()) return; break; } case Direction::Backward: { - if (!layout_wraps() && m_clients.active_index() == 0) + if (!layout_wraps() && m_views.active_index() == 0) return; break; } } - m_clients.cycle_active(direction); - mp_active = m_clients.active_element().value_or(nullptr); + m_views.cycle_active(direction); + mp_active = m_views.active_element().value_or(nullptr); } void @@ -199,174 +199,174 @@ Workspace::drag(Direction direction) switch (direction) { case Direction::Forward: { - if (!layout_wraps() && m_clients.active_index() == m_clients.last_index()) + if (!layout_wraps() && m_views.active_index() == m_views.last_index()) return; break; } case Direction::Backward: { - if (!layout_wraps() && m_clients.active_index() == 0) + if (!layout_wraps() && m_views.active_index() == 0) return; break; } } - m_clients.drag_active(direction); - mp_active = m_clients.active_element().value_or(nullptr); + m_views.drag_active(direction); + mp_active = m_views.active_element().value_or(nullptr); } void Workspace::reverse() { - m_clients.reverse(); - mp_active = m_clients.active_element().value_or(nullptr); + m_views.reverse(); + mp_active = m_views.active_element().value_or(nullptr); } void Workspace::rotate(Direction direction) { - m_clients.rotate(direction); - mp_active = m_clients.active_element().value_or(nullptr); + m_views.rotate(direction); + mp_active = m_views.active_element().value_or(nullptr); } void Workspace::shuffle_main(Direction direction) { - m_clients.rotate_range( + m_views.rotate_range( direction, 0, static_cast<Index>(m_layout_handler.main_count()) ); - mp_active = m_clients.active_element().value_or(nullptr); + mp_active = m_views.active_element().value_or(nullptr); } void Workspace::shuffle_stack(Direction direction) { - m_clients.rotate_range( + m_views.rotate_range( direction, static_cast<Index>(m_layout_handler.main_count()), - m_clients.size() + m_views.size() ); - mp_active = m_clients.active_element().value_or(nullptr); + mp_active = m_views.active_element().value_or(nullptr); } void -Workspace::activate_client(Client_ptr client) +Workspace::activate_view(View_ptr view) { - if (m_clients.contains(client)) { - m_clients.activate_element(client); - mp_active = client; + if (m_views.contains(view)) { + m_views.activate_element(view); + mp_active = view; } } void -Workspace::add_client(Client_ptr client) +Workspace::add_view(View_ptr view) { - if (m_clients.contains(client)) + if (m_views.contains(view)) return; - m_clients.insert_at_back(client); - mp_active = client; + m_views.insert_at_back(view); + mp_active = view; } void -Workspace::remove_client(Client_ptr client) +Workspace::remove_view(View_ptr view) { - m_clients.remove_element(client); - mp_active = m_clients.active_element().value_or(nullptr); + m_views.remove_element(view); + mp_active = m_views.active_element().value_or(nullptr); } void -Workspace::replace_client(Client_ptr client, Client_ptr replacement) +Workspace::replace_view(View_ptr view, View_ptr replacement) { bool was_active - = m_clients.active_element().value_or(nullptr) == client; + = m_views.active_element().value_or(nullptr) == view; - m_clients.replace_element(client, replacement); + m_views.replace_element(view, replacement); if (was_active) { - m_clients.activate_element(replacement); + m_views.activate_element(replacement); mp_active = replacement; } } void -Workspace::client_to_icon(Client_ptr client) +Workspace::view_to_icon(View_ptr view) { - if (m_clients.remove_element(client)) - m_icons.insert_at_back(client); + if (m_views.remove_element(view)) + m_iconified_views.insert_at_back(view); - mp_active = m_clients.active_element().value_or(nullptr); + mp_active = m_views.active_element().value_or(nullptr); } void -Workspace::icon_to_client(Client_ptr client) +Workspace::icon_to_view(View_ptr view) { - if (m_icons.remove_element(client)) - m_clients.insert_at_back(client); + if (m_iconified_views.remove_element(view)) + m_views.insert_at_back(view); - mp_active = m_clients.active_element().value_or(nullptr); + mp_active = m_views.active_element().value_or(nullptr); } void -Workspace::add_icon(Client_ptr client) +Workspace::add_icon(View_ptr view) { - if (m_icons.contains(client)) + if (m_iconified_views.contains(view)) return; - m_icons.insert_at_back(client); + m_iconified_views.insert_at_back(view); } void -Workspace::remove_icon(Client_ptr client) +Workspace::remove_icon(View_ptr view) { - m_icons.remove_element(client); + m_iconified_views.remove_element(view); } -std::optional<Client_ptr> +std::optional<View_ptr> Workspace::pop_icon() { - return m_icons.empty() + return m_iconified_views.empty() ? std::nullopt - : std::optional(m_icons[m_icons.size() - 1]); + : std::optional(m_iconified_views[m_iconified_views.size() - 1]); } void -Workspace::client_to_disowned(Client_ptr client) +Workspace::view_to_disowned(View_ptr view) { - if (m_clients.remove_element(client)) - m_disowned.insert_at_back(client); + if (m_views.remove_element(view)) + m_disowned_views.insert_at_back(view); - mp_active = m_clients.active_element().value_or(nullptr); + mp_active = m_views.active_element().value_or(nullptr); } void -Workspace::disowned_to_client(Client_ptr client) +Workspace::disowned_to_view(View_ptr view) { - if (m_disowned.remove_element(client)) - m_clients.insert_at_back(client); + if (m_disowned_views.remove_element(view)) + m_views.insert_at_back(view); - mp_active = m_clients.active_element().value_or(nullptr); + mp_active = m_views.active_element().value_or(nullptr); } void -Workspace::add_disowned(Client_ptr client) +Workspace::add_disowned(View_ptr view) { - if (m_disowned.contains(client)) + if (m_disowned_views.contains(view)) return; - m_disowned.insert_at_back(client); + m_disowned_views.insert_at_back(view); } void -Workspace::remove_disowned(Client_ptr client) +Workspace::remove_disowned(View_ptr view) { - m_disowned.remove_element(client); + m_disowned_views.remove_element(view); } void @@ -464,34 +464,34 @@ Workspace::set_layout(LayoutHandler::LayoutKind layout) std::vector<Placement> Workspace::arrange(Region region) const { - std::deque<Client_ptr> clients = m_clients.as_deque(); + std::deque<View_ptr> views = m_views.as_deque(); std::vector<Placement> placements; - placements.reserve(clients.size()); + placements.reserve(views.size()); auto fullscreen_iter = std::stable_partition( - clients.begin(), - clients.end(), - [](const Client_ptr client) -> bool { - return client->m_fullscreen && !client->m_contained; + views.begin(), + views.end(), + [](const View_ptr view) -> bool { + return view->m_fullscreen && !view->m_contained; } ); auto free_iter = std::stable_partition( fullscreen_iter, - clients.end(), - [=,this](const Client_ptr client) -> bool { - return !layout_is_free() && Client::is_free(client); + views.end(), + [=,this](const View_ptr view) -> bool { + return !layout_is_free() && View::is_free(view); } ); std::transform( - clients.begin(), + views.begin(), fullscreen_iter, std::back_inserter(placements), - [region](const Client_ptr client) -> Placement { + [region](const View_ptr view) -> Placement { return Placement { Placement::PlacementMethod::Tile, - client, + view, NO_DECORATION, region }; @@ -502,12 +502,12 @@ Workspace::arrange(Region region) const fullscreen_iter, free_iter, std::back_inserter(placements), - [](const Client_ptr client) -> Placement { + [](const View_ptr view) -> Placement { return Placement { Placement::PlacementMethod::Free, - client, + view, FREE_DECORATION, - client->m_free_region + view->m_free_region }; } ); @@ -516,7 +516,7 @@ Workspace::arrange(Region region) const region, placements, free_iter, - clients.end() + views.end() ); if (layout_is_single()) { @@ -524,7 +524,7 @@ Workspace::arrange(Region region) const placements.begin(), placements.end(), [](Placement& placement) { - if (!placement.client->m_focused) + if (!placement.view->m_focused) placement.region = std::nullopt; } );