commit cf8ac9d10ca9745668f752825c5618555d209b84
parent 378bbc4e4b832ef15a20d0da5a057eb503c71745
Author: deurzen <max@deurzen.net>
Date: Sun, 29 May 2022 08:07:49 +0200
adds cursor input processing, cursor bindings
Diffstat:
26 files changed, 1088 insertions(+), 1189 deletions(-)
diff --git a/include/kranewl/conf/config.hh b/include/kranewl/conf/config.hh
@@ -13,7 +13,7 @@ extern "C" {
struct Config final {
KeyBindings key_bindings;
- MouseBindings mouse_bindings;
+ CursorBindings cursor_bindings;
};
class ConfigParser final {
diff --git a/include/kranewl/input/bindings.hh b/include/kranewl/input/bindings.hh
@@ -1,7 +1,7 @@
#pragma once
#include <kranewl/input/keyboard.hh>
-#include <kranewl/input/mouse.hh>
+#include <kranewl/input/cursor.hh>
#include <cstdint>
#include <functional>
@@ -16,12 +16,12 @@ typedef
typedef
std::function<bool(Model&, View_ptr)>
- MouseAction;
+ CursorAction;
typedef
std::unordered_map<KeyboardInput, KeyboardAction>
KeyBindings;
typedef
- std::unordered_map<MouseInput, MouseAction>
- MouseBindings;
+ std::unordered_map<CursorInput, CursorAction>
+ CursorBindings;
diff --git a/include/kranewl/input/cursor-bindings.hh b/include/kranewl/input/cursor-bindings.hh
@@ -0,0 +1,162 @@
+#pragma once
+
+#include <kranewl/input/bindings.hh>
+#include <kranewl/input/cursor.hh>
+#include <kranewl/layout.hh>
+#include <kranewl/model.hh>
+
+extern "C" {
+#include <linux/input-event-codes.h>
+#include <wlr/types/wlr_keyboard.h>
+}
+
+#ifdef NDEBUG
+#define MODKEY WLR_MODIFIER_LOGO
+#define SECKEY WLR_MODIFIER_ALT
+#else
+#define MODKEY WLR_MODIFIER_ALT
+#define SECKEY WLR_MODIFIER_LOGO
+#endif
+#define SHIFT WLR_MODIFIER_SHIFT
+#define CAPS WLR_MODIFIER_CAPS
+#define CTRL WLR_MODIFIER_CTRL
+#define ALT WLR_MODIFIER_ALT
+#define MOD2 WLR_MODIFIER_MOD2
+#define MOD3 WLR_MODIFIER_MOD3
+#define LOGO WLR_MODIFIER_LOGO
+#define MOD5 WLR_MODIFIER_MOD5
+#define GLOBAL CursorInput::Target::Global
+#define ROOT CursorInput::Target::Root
+#define VIEW CursorInput::Target::View
+#define LEFT CursorInput::Button::Left
+#define RIGHT CursorInput::Button::Right
+#define MIDDLE CursorInput::Button::Middle
+#define SCROLLUP CursorInput::Button::ScrollUp
+#define SCROLLDOWN CursorInput::Button::ScrollDown
+#define SCROLLLEFT CursorInput::Button::ScrollLeft
+#define SCROLLRIGHT CursorInput::Button::ScrollRight
+#define FORWARD CursorInput::Button::Forward
+#define BACKWARD CursorInput::Button::Backward
+#define CALL_FOCUS(args) [](Model& model, View_ptr view) {{args} return true;}
+#define CALL_NOFOCUS(args) [](Model& model, View_ptr view) {{args} return false;}
+#define CALL_EXTERNAL(command) CALL(spawn_external(#command))
+
+namespace Bindings {
+
+static const CursorBindings cursor_bindings = {
+{ { VIEW, RIGHT, MODKEY | CTRL },
+ CALL_FOCUS({
+ if (view)
+ model.set_floating_view(Toggle::Reverse, view);
+ })
+},
+{ { VIEW, MIDDLE, MODKEY | CTRL | SHIFT },
+ CALL_FOCUS({
+ if (view)
+ model.set_fullscreen_view(Toggle::Reverse, view);
+ })
+},
+{ { VIEW, MIDDLE, MODKEY },
+ CALL_FOCUS({
+ if (view)
+ model.center_view(view);
+ })
+},
+{ { VIEW, SCROLLDOWN, MODKEY | CTRL | SHIFT },
+ CALL_FOCUS({
+ if (view)
+ model.inflate_view(-16, view);
+ })
+},
+{ { VIEW, SCROLLUP, MODKEY | CTRL | SHIFT },
+ CALL_FOCUS({
+ if (view)
+ model.inflate_view(16, view);
+ })
+},
+{ { VIEW, LEFT, MODKEY },
+ CALL_FOCUS({
+ /* if (view) */
+ /* model.start_moving(view); */
+ })
+},
+{ { VIEW, RIGHT, MODKEY },
+ CALL_FOCUS({
+ /* if (view) */
+ /* model.start_resizing(view); */
+ })
+},
+{ { GLOBAL, SCROLLDOWN, MODKEY },
+ CALL_NOFOCUS({
+ model.cycle_focus(Direction::Forward);
+ })
+},
+{ { GLOBAL, SCROLLUP, MODKEY },
+ CALL_NOFOCUS({
+ model.cycle_focus(Direction::Backward);
+ })
+},
+{ { GLOBAL, SCROLLDOWN, MODKEY | SHIFT },
+ CALL_NOFOCUS({
+ /* model.activate_next_workspace(Direction::Forward); */
+ })
+},
+{ { GLOBAL, SCROLLUP, MODKEY | SHIFT },
+ CALL_NOFOCUS({
+ /* model.activate_next_workspace(Direction::Backward); */
+ })
+},
+{ { VIEW, FORWARD, MODKEY },
+ CALL_NOFOCUS({
+ /* if (view) */
+ /* model.move_view_to_next_workspace(Direction::Forward, view); */
+ })
+},
+{ { VIEW, BACKWARD, MODKEY },
+ CALL_NOFOCUS({
+ /* if (view) */
+ /* model.move_view_to_next_workspace(Direction::Backward, view); */
+ })
+},
+{ { VIEW, RIGHT, MODKEY | CTRL | SHIFT },
+ CALL_NOFOCUS({
+ if (view)
+ model.kill_view(view);
+ })
+},
+{ { GLOBAL, LEFT, MODKEY | SECKEY | CTRL },
+ CALL_NOFOCUS({
+ model.spawn_external("alacritty --class kranewl:cf,Alacritty");
+ })
+},
+};
+
+}
+
+#undef CALL_EXTERNAL
+#undef CALL_NOFOCUS
+#undef CALL_FOCUS
+#undef BACKWARD
+#undef FORWARD
+#undef SCROLLRIGHT
+#undef SCROLLLEFT
+#undef SCROLLDOWN
+#undef SCROLLUP
+#undef MIDDLE
+#undef RIGHT
+#undef LEFT
+#undef VIEW
+#undef ROOT
+#undef GLOBAL
+#undef MOD5
+#undef LOGO
+#undef MOD3
+#undef MOD2
+#undef ALT
+#undef CTRL
+#undef CAPS
+#undef SHIFT
+#undef SECKEY
+#undef MODKEY
+#undef SECKEY
+#undef MODKEY
diff --git a/include/kranewl/input/cursor.hh b/include/kranewl/input/cursor.hh
@@ -0,0 +1,121 @@
+#pragma once
+
+#include <kranewl/geometry.hh>
+
+extern "C" {
+#include <linux/input-event-codes.h>
+#include <wlr/backend.h>
+#include <xkbcommon/xkbcommon.h>
+}
+
+#include <cstdint>
+#include <unordered_set>
+
+struct CursorInput {
+ enum class Target
+ {
+ Global,
+ Root,
+ View
+ };
+
+ enum Button : uint32_t {
+ Left = BTN_LEFT,
+ Right = BTN_RIGHT,
+ Middle = BTN_MIDDLE,
+ Forward = BTN_SIDE,
+ Backward = BTN_EXTRA,
+ ScrollUp = KEY_MAX + 1,
+ ScrollDown = KEY_MAX + 2,
+ ScrollLeft = KEY_MAX + 3,
+ ScrollRight = KEY_MAX + 4,
+ };
+
+ Target target;
+ Button button;
+ uint32_t modifiers;
+};
+
+typedef class Server* Server_ptr;
+typedef class Seat* Seat_ptr;
+typedef struct View* View_ptr;
+
+typedef struct Cursor {
+ enum class CursorMode {
+ Passthrough,
+ Move,
+ Resize,
+ };
+
+ Cursor(
+ Server_ptr,
+ Seat_ptr,
+ struct wlr_cursor*,
+ struct wlr_pointer_constraints_v1*,
+ struct wlr_relative_pointer_manager_v1*,
+ struct wlr_virtual_pointer_manager_v1*
+ );
+ ~Cursor();
+
+ View_ptr view_under_cursor() const;
+
+ static void handle_cursor_motion(struct wl_listener*, void*);
+ static void handle_cursor_motion_absolute(struct wl_listener*, void*);
+ static void handle_cursor_button(struct wl_listener*, void*);
+ static void handle_cursor_axis(struct wl_listener*, void*);
+ static void handle_cursor_frame(struct wl_listener*, void*);
+ static void handle_request_start_drag(struct wl_listener*, void*);
+ static void handle_start_drag(struct wl_listener*, void*);
+ static void handle_request_set_cursor(struct wl_listener*, void*);
+
+ Server_ptr mp_server;
+ Seat_ptr mp_seat;
+
+ CursorMode m_cursor_mode;
+ struct wlr_cursor* mp_wlr_cursor;
+ 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;
+
+ struct {
+ View_ptr view;
+ double x, y;
+ Region region;
+ uint32_t resize_edges;
+ } m_grab_state;
+
+ struct wl_listener ml_cursor_motion;
+ struct wl_listener ml_cursor_motion_absolute;
+ struct wl_listener ml_cursor_button;
+ struct wl_listener ml_cursor_axis;
+ struct wl_listener ml_cursor_frame;
+ struct wl_listener ml_request_start_drag;
+ struct wl_listener ml_start_drag;
+ struct wl_listener ml_request_set_cursor;
+
+}* Cursor_ptr;
+
+inline bool
+operator==(CursorInput const& lhs, CursorInput const& rhs)
+{
+ return lhs.target == rhs.target
+ && lhs.button == rhs.button
+ && lhs.modifiers == rhs.modifiers;
+}
+
+namespace std
+{
+ template <>
+ struct hash<CursorInput> {
+ std::size_t
+ operator()(CursorInput const& input) const
+ {
+ std::size_t target_hash = std::hash<CursorInput::Target>()(input.target);
+ std::size_t modifiers_hash = std::hash<uint32_t>()(input.modifiers);
+ std::size_t button_hash = std::hash<uint32_t>()(input.button);
+
+ return target_hash ^ modifiers_hash ^ button_hash;
+ }
+ };
+}
diff --git a/include/kranewl/input/key-bindings.hh b/include/kranewl/input/key-bindings.hh
@@ -0,0 +1,313 @@
+#pragma once
+
+#include <kranewl/input/bindings.hh>
+#include <kranewl/layout.hh>
+#include <kranewl/model.hh>
+
+extern "C" {
+#include <wlr/types/wlr_keyboard.h>
+}
+
+#ifdef NDEBUG
+#define MODKEY WLR_MODIFIER_LOGO
+#define SECKEY WLR_MODIFIER_ALT
+#else
+#define MODKEY WLR_MODIFIER_ALT
+#define SECKEY WLR_MODIFIER_LOGO
+#endif
+#define SHIFT WLR_MODIFIER_SHIFT
+#define CAPS WLR_MODIFIER_CAPS
+#define CTRL WLR_MODIFIER_CTRL
+#define ALT WLR_MODIFIER_ALT
+#define MOD2 WLR_MODIFIER_MOD2
+#define MOD3 WLR_MODIFIER_MOD3
+#define LOGO WLR_MODIFIER_LOGO
+#define MOD5 WLR_MODIFIER_MOD5
+#define CALL(args) [](Model& model) {model.args;}
+#define CALL_EXTERNAL(command) CALL(spawn_external(#command))
+
+namespace Bindings {
+
+static const KeyBindings key_bindings = {
+{ { XKB_KEY_Q, MODKEY | CTRL | SHIFT },
+ CALL(exit())
+},
+
+// view state modifiers
+{ { XKB_KEY_c, MODKEY },
+ CALL(kill_focus())
+},
+{ { XKB_KEY_space, MODKEY | SHIFT },
+ CALL(set_floating_focus(Toggle::Reverse))
+},
+{ { XKB_KEY_f, MODKEY },
+ CALL(set_fullscreen_focus(Toggle::Reverse))
+},
+{ { XKB_KEY_x, MODKEY },
+ CALL(set_sticky_focus(Toggle::Reverse))
+},
+{ { XKB_KEY_f, MODKEY | SECKEY | CTRL },
+ CALL(set_contained_focus(Toggle::Reverse))
+},
+{ { XKB_KEY_i, MODKEY | SECKEY | CTRL },
+ CALL(set_invincible_focus(Toggle::Reverse))
+},
+{ { XKB_KEY_y, MODKEY },
+ CALL(set_iconify_focus(Toggle::Reverse))
+},
+{ { XKB_KEY_u, MODKEY },
+ CALL(pop_deiconify())
+},
+{ { XKB_KEY_u, MODKEY | SECKEY },
+ CALL(deiconify_all())
+},
+
+// view arrangers
+{ { XKB_KEY_space, MODKEY | CTRL },
+ CALL(center_focus())
+},
+{ { XKB_KEY_h, MODKEY | CTRL },
+ [](Model& model) {
+ View_ptr focus = model.focused_view();
+
+ if (focus && model.is_free(focus))
+ model.nudge_focus(Edge::Left, 15);
+ else
+ model.shuffle_main(Direction::Backward);
+ }
+},
+{ { XKB_KEY_j, MODKEY | CTRL },
+ [](Model& model) {
+ View_ptr focus = model.focused_view();
+
+ if (focus && model.is_free(focus))
+ model.nudge_focus(Edge::Bottom, 15);
+ else
+ model.shuffle_stack(Direction::Forward);
+ }
+},
+{ { XKB_KEY_k, MODKEY | CTRL },
+ [](Model& model) {
+ View_ptr focus = model.focused_view();
+
+ if (focus && model.is_free(focus))
+ model.nudge_focus(Edge::Top, 15);
+ else
+ model.shuffle_stack(Direction::Backward);
+ }
+},
+{ { XKB_KEY_l, MODKEY | CTRL },
+ [](Model& model) {
+ View_ptr focus = model.focused_view();
+
+ if (focus && model.is_free(focus))
+ model.nudge_focus(Edge::Right, 15);
+ else
+ model.shuffle_main(Direction::Forward);
+ }
+},
+{ { XKB_KEY_H, MODKEY | CTRL | SHIFT },
+ CALL(stretch_focus(Edge::Left, 15))
+},
+{ { XKB_KEY_J, MODKEY | CTRL | SHIFT },
+ CALL(stretch_focus(Edge::Bottom, 15))
+},
+{ { XKB_KEY_K, MODKEY | CTRL | SHIFT },
+ CALL(stretch_focus(Edge::Top, 15))
+},
+{ { XKB_KEY_L, MODKEY | CTRL | SHIFT },
+ CALL(stretch_focus(Edge::Right, 15))
+},
+{ { XKB_KEY_Y, MODKEY | CTRL | SHIFT },
+ CALL(stretch_focus(Edge::Left, -15))
+},
+{ { XKB_KEY_U, MODKEY | CTRL | SHIFT },
+ CALL(stretch_focus(Edge::Bottom, -15))
+},
+{ { XKB_KEY_I, MODKEY | CTRL | SHIFT },
+ CALL(stretch_focus(Edge::Top, -15))
+},
+{ { XKB_KEY_O, MODKEY | CTRL | SHIFT },
+ CALL(stretch_focus(Edge::Right, -15))
+},
+{ { XKB_KEY_leftarrow, MODKEY | CTRL },
+ CALL(snap_focus(Edge::Left))
+},
+{ { XKB_KEY_downarrow, MODKEY | CTRL },
+ CALL(snap_focus(Edge::Bottom))
+},
+{ { XKB_KEY_uparrow, MODKEY | CTRL },
+ CALL(snap_focus(Edge::Top))
+},
+{ { XKB_KEY_rightarrow, MODKEY | CTRL },
+ CALL(snap_focus(Edge::Right))
+},
+{ { XKB_KEY_j, MODKEY },
+ CALL(cycle_focus(Direction::Forward))
+},
+{ { XKB_KEY_k, MODKEY },
+ CALL(cycle_focus(Direction::Backward))
+},
+{ { XKB_KEY_J, MODKEY | SHIFT },
+ CALL(drag_focus(Direction::Forward))
+},
+{ { XKB_KEY_K, MODKEY | SHIFT },
+ CALL(drag_focus(Direction::Backward))
+},
+{ { XKB_KEY_r, MODKEY },
+ CALL(reverse_views())
+},
+{ { XKB_KEY_semicolon, MODKEY | SHIFT },
+ CALL(rotate_views(Direction::Forward))
+},
+{ { XKB_KEY_comma, MODKEY | SHIFT },
+ CALL(rotate_views(Direction::Backward))
+},
+
+// workspace layout modifiers
+{ { XKB_KEY_F, MODKEY | SHIFT },
+ CALL(set_layout(LayoutHandler::LayoutKind::Float))
+},
+{ { XKB_KEY_L, MODKEY | SHIFT },
+ CALL(set_layout(LayoutHandler::LayoutKind::FramelessFloat))
+},
+{ { XKB_KEY_z, MODKEY },
+ CALL(set_layout(LayoutHandler::LayoutKind::SingleFloat))
+},
+{ { XKB_KEY_Z, MODKEY | SHIFT },
+ CALL(set_layout(LayoutHandler::LayoutKind::FramelessSingleFloat))
+},
+{ { XKB_KEY_m, MODKEY },
+ CALL(set_layout(LayoutHandler::LayoutKind::Monocle))
+},
+{ { XKB_KEY_d, MODKEY | CTRL },
+ CALL(set_layout(LayoutHandler::LayoutKind::MainDeck))
+},
+{ { XKB_KEY_D, MODKEY | SHIFT },
+ CALL(set_layout(LayoutHandler::LayoutKind::StackDeck))
+},
+{ { XKB_KEY_D, MODKEY | CTRL | SHIFT },
+ CALL(set_layout(LayoutHandler::LayoutKind::DoubleDeck))
+},
+{ { XKB_KEY_g, MODKEY },
+ CALL(set_layout(LayoutHandler::LayoutKind::Center))
+},
+{ { XKB_KEY_t, MODKEY },
+ CALL(set_layout(LayoutHandler::LayoutKind::DoubleStack))
+},
+{ { XKB_KEY_T, MODKEY | SHIFT },
+ CALL(set_layout(LayoutHandler::LayoutKind::CompactDoubleStack))
+},
+{ { XKB_KEY_P, MODKEY | CTRL | SHIFT },
+ CALL(set_layout(LayoutHandler::LayoutKind::Paper))
+},
+{ { XKB_KEY_P, MODKEY | SECKEY | CTRL | SHIFT },
+ CALL(set_layout(LayoutHandler::LayoutKind::CompactPaper))
+},
+{ { XKB_KEY_Y, MODKEY | SHIFT },
+ CALL(set_layout(LayoutHandler::LayoutKind::HorizontalStack))
+},
+{ { XKB_KEY_y, MODKEY | CTRL },
+ CALL(set_layout(LayoutHandler::LayoutKind::CompactHorizontalStack))
+},
+{ { XKB_KEY_V, MODKEY | SHIFT },
+ CALL(set_layout(LayoutHandler::LayoutKind::VerticalStack))
+},
+{ { XKB_KEY_V, MODKEY | CTRL },
+ CALL(set_layout(LayoutHandler::LayoutKind::CompactVerticalStack))
+},
+{ { XKB_KEY_F, MODKEY | CTRL | SHIFT },
+ CALL(set_layout_retain_region(LayoutHandler::LayoutKind::Float))
+},
+{ { XKB_KEY_space, MODKEY },
+ CALL(toggle_layout())
+},
+{ { XKB_KEY_Return, MODKEY },
+ CALL_EXTERNAL(alacritty)
+},
+
+// workspace layout data modifiers
+{ { XKB_KEY_equal, MODKEY },
+ CALL(change_gap_size(2))
+},
+{ { XKB_KEY_minus, MODKEY },
+ CALL(change_gap_size(-2))
+},
+{ { XKB_KEY_equal, MODKEY | SHIFT },
+ CALL(reset_gap_size())
+},
+{ { XKB_KEY_i, MODKEY },
+ CALL(change_main_count(1))
+},
+{ { XKB_KEY_d, MODKEY },
+ CALL(change_main_count(-1))
+},
+{ { XKB_KEY_l, MODKEY },
+ CALL(change_main_factor(.05f))
+},
+{ { XKB_KEY_h, MODKEY },
+ CALL(change_main_factor(-.05f))
+},
+{ { XKB_KEY_Page_Up, MODKEY | SHIFT },
+ CALL(change_margin(5))
+},
+{ { XKB_KEY_Page_Down, MODKEY | SHIFT },
+ CALL(change_margin(-5))
+},
+{ { XKB_KEY_Left, MODKEY | SHIFT },
+ CALL(change_margin(Edge::Left, 5))
+},
+{ { XKB_KEY_Left, MODKEY | CTRL | SHIFT },
+ CALL(change_margin(Edge::Left, -5))
+},
+{ { XKB_KEY_Up, MODKEY | SHIFT },
+ CALL(change_margin(Edge::Top, 5))
+},
+{ { XKB_KEY_Up, MODKEY | CTRL | SHIFT },
+ CALL(change_margin(Edge::Top, -5))
+},
+{ { XKB_KEY_Right, MODKEY | SHIFT },
+ CALL(change_margin(Edge::Right, 5))
+},
+{ { XKB_KEY_Right, MODKEY | CTRL | SHIFT },
+ CALL(change_margin(Edge::Right, -5))
+},
+{ { XKB_KEY_Down, MODKEY | SHIFT },
+ CALL(change_margin(Edge::Bottom, 5))
+},
+{ { XKB_KEY_Down, MODKEY | CTRL | SHIFT },
+ CALL(change_margin(Edge::Bottom, -5))
+},
+{ { XKB_KEY_comma, MODKEY | CTRL | SHIFT },
+ CALL(cycle_layout_data(Direction::Backward))
+},
+{ { XKB_KEY_period, MODKEY | CTRL | SHIFT },
+ CALL(cycle_layout_data(Direction::Forward))
+},
+{ { XKB_KEY_slash, MODKEY | CTRL | SHIFT },
+ CALL(toggle_layout_data())
+},
+{ { XKB_KEY_Delete, MODKEY | CTRL | SHIFT },
+ CALL(copy_data_from_prev_layout())
+},
+{ { XKB_KEY_equal, MODKEY | CTRL | SHIFT },
+ CALL(reset_margin())
+},
+{ { XKB_KEY_equal, MODKEY | SECKEY | CTRL | SHIFT },
+ CALL(reset_layout_data())
+},
+};
+
+}
+#undef CALL_EXTERNAL
+#undef CALL
+#undef MOD5
+#undef LOGO
+#undef MOD3
+#undef MOD2
+#undef ALT
+#undef CTRL
+#undef CAPS
+#undef SHIFT
+#undef SECKEY
+#undef MODKEY
diff --git a/include/kranewl/input/keybindings.hh b/include/kranewl/input/keybindings.hh
@@ -1,313 +0,0 @@
-#pragma once
-
-#include <kranewl/input/bindings.hh>
-#include <kranewl/model.hh>
-#include <kranewl/layout.hh>
-
-extern "C" {
-#include <wlr/types/wlr_keyboard.h>
-}
-
-#ifdef NDEBUG
-#define MODKEY WLR_MODIFIER_LOGO
-#define SECKEY WLR_MODIFIER_ALT
-#else
-#define MODKEY WLR_MODIFIER_ALT
-#define SECKEY WLR_MODIFIER_LOGO
-#endif
-#define SHIFT WLR_MODIFIER_SHIFT
-#define CAPS WLR_MODIFIER_CAPS
-#define CTRL WLR_MODIFIER_CTRL
-#define ALT WLR_MODIFIER_ALT
-#define MOD2 WLR_MODIFIER_MOD2
-#define MOD3 WLR_MODIFIER_MOD3
-#define LOGO WLR_MODIFIER_LOGO
-#define MOD5 WLR_MODIFIER_MOD5
-#define CALL(args) [](Model& model) {model.args;}
-#define CALL_EXTERNAL(command) CALL(spawn_external(#command))
-
-namespace Bindings {
-
-static const KeyBindings key_bindings = {
-{ { XKB_KEY_Q, MODKEY | CTRL | SHIFT },
- CALL(exit())
-},
-
-// view state modifiers
-{ { XKB_KEY_c, MODKEY },
- CALL(kill_focus())
-},
-{ { XKB_KEY_space, MODKEY | SHIFT },
- CALL(set_floating_focus(Toggle::Reverse))
-},
-{ { XKB_KEY_f, MODKEY },
- CALL(set_fullscreen_focus(Toggle::Reverse))
-},
-{ { XKB_KEY_x, MODKEY },
- CALL(set_sticky_focus(Toggle::Reverse))
-},
-{ { XKB_KEY_f, MODKEY | SECKEY | CTRL },
- CALL(set_contained_focus(Toggle::Reverse))
-},
-{ { XKB_KEY_i, MODKEY | SECKEY | CTRL },
- CALL(set_invincible_focus(Toggle::Reverse))
-},
-{ { XKB_KEY_y, MODKEY },
- CALL(set_iconify_focus(Toggle::Reverse))
-},
-{ { XKB_KEY_u, MODKEY },
- CALL(pop_deiconify())
-},
-{ { XKB_KEY_u, MODKEY | SECKEY },
- CALL(deiconify_all())
-},
-
-// view arrangers
-{ { XKB_KEY_space, MODKEY | CTRL },
- CALL(center_focus())
-},
-{ { XKB_KEY_h, MODKEY | CTRL },
- [](Model& model) {
- View_ptr focus = model.focused_view();
-
- if (focus && model.is_free(focus))
- model.nudge_focus(Edge::Left, 15);
- else
- model.shuffle_main(Direction::Backward);
- }
-},
-{ { XKB_KEY_j, MODKEY | CTRL },
- [](Model& model) {
- View_ptr focus = model.focused_view();
-
- if (focus && model.is_free(focus))
- model.nudge_focus(Edge::Bottom, 15);
- else
- model.shuffle_stack(Direction::Forward);
- }
-},
-{ { XKB_KEY_k, MODKEY | CTRL },
- [](Model& model) {
- View_ptr focus = model.focused_view();
-
- if (focus && model.is_free(focus))
- model.nudge_focus(Edge::Top, 15);
- else
- model.shuffle_stack(Direction::Backward);
- }
-},
-{ { XKB_KEY_l, MODKEY | CTRL },
- [](Model& model) {
- View_ptr focus = model.focused_view();
-
- if (focus && model.is_free(focus))
- model.nudge_focus(Edge::Right, 15);
- else
- model.shuffle_main(Direction::Forward);
- }
-},
-{ { XKB_KEY_H, MODKEY | CTRL | SHIFT },
- CALL(stretch_focus(Edge::Left, 15))
-},
-{ { XKB_KEY_J, MODKEY | CTRL | SHIFT },
- CALL(stretch_focus(Edge::Bottom, 15))
-},
-{ { XKB_KEY_K, MODKEY | CTRL | SHIFT },
- CALL(stretch_focus(Edge::Top, 15))
-},
-{ { XKB_KEY_L, MODKEY | CTRL | SHIFT },
- CALL(stretch_focus(Edge::Right, 15))
-},
-{ { XKB_KEY_Y, MODKEY | CTRL | SHIFT },
- CALL(stretch_focus(Edge::Left, -15))
-},
-{ { XKB_KEY_U, MODKEY | CTRL | SHIFT },
- CALL(stretch_focus(Edge::Bottom, -15))
-},
-{ { XKB_KEY_I, MODKEY | CTRL | SHIFT },
- CALL(stretch_focus(Edge::Top, -15))
-},
-{ { XKB_KEY_O, MODKEY | CTRL | SHIFT },
- CALL(stretch_focus(Edge::Right, -15))
-},
-{ { XKB_KEY_leftarrow, MODKEY | CTRL },
- CALL(snap_focus(Edge::Left))
-},
-{ { XKB_KEY_downarrow, MODKEY | CTRL },
- CALL(snap_focus(Edge::Bottom))
-},
-{ { XKB_KEY_uparrow, MODKEY | CTRL },
- CALL(snap_focus(Edge::Top))
-},
-{ { XKB_KEY_rightarrow, MODKEY | CTRL },
- CALL(snap_focus(Edge::Right))
-},
-{ { XKB_KEY_j, MODKEY },
- CALL(cycle_focus(Direction::Forward))
-},
-{ { XKB_KEY_k, MODKEY },
- CALL(cycle_focus(Direction::Backward))
-},
-{ { XKB_KEY_J, MODKEY | SHIFT },
- CALL(drag_focus(Direction::Forward))
-},
-{ { XKB_KEY_K, MODKEY | SHIFT },
- CALL(drag_focus(Direction::Backward))
-},
-{ { XKB_KEY_r, MODKEY },
- CALL(reverse_views())
-},
-{ { XKB_KEY_semicolon, MODKEY | SHIFT },
- CALL(rotate_views(Direction::Forward))
-},
-{ { XKB_KEY_comma, MODKEY | SHIFT },
- CALL(rotate_views(Direction::Backward))
-},
-
-// workspace layout modifiers
-{ { XKB_KEY_F, MODKEY | SHIFT },
- CALL(set_layout(LayoutHandler::LayoutKind::Float))
-},
-{ { XKB_KEY_L, MODKEY | SHIFT },
- CALL(set_layout(LayoutHandler::LayoutKind::FramelessFloat))
-},
-{ { XKB_KEY_z, MODKEY },
- CALL(set_layout(LayoutHandler::LayoutKind::SingleFloat))
-},
-{ { XKB_KEY_Z, MODKEY | SHIFT },
- CALL(set_layout(LayoutHandler::LayoutKind::FramelessSingleFloat))
-},
-{ { XKB_KEY_m, MODKEY },
- CALL(set_layout(LayoutHandler::LayoutKind::Monocle))
-},
-{ { XKB_KEY_d, MODKEY | CTRL },
- CALL(set_layout(LayoutHandler::LayoutKind::MainDeck))
-},
-{ { XKB_KEY_D, MODKEY | SHIFT },
- CALL(set_layout(LayoutHandler::LayoutKind::StackDeck))
-},
-{ { XKB_KEY_D, MODKEY | CTRL | SHIFT },
- CALL(set_layout(LayoutHandler::LayoutKind::DoubleDeck))
-},
-{ { XKB_KEY_g, MODKEY },
- CALL(set_layout(LayoutHandler::LayoutKind::Center))
-},
-{ { XKB_KEY_t, MODKEY },
- CALL(set_layout(LayoutHandler::LayoutKind::DoubleStack))
-},
-{ { XKB_KEY_T, MODKEY | SHIFT },
- CALL(set_layout(LayoutHandler::LayoutKind::CompactDoubleStack))
-},
-{ { XKB_KEY_P, MODKEY | CTRL | SHIFT },
- CALL(set_layout(LayoutHandler::LayoutKind::Paper))
-},
-{ { XKB_KEY_P, MODKEY | SECKEY | CTRL | SHIFT },
- CALL(set_layout(LayoutHandler::LayoutKind::CompactPaper))
-},
-{ { XKB_KEY_Y, MODKEY | SHIFT },
- CALL(set_layout(LayoutHandler::LayoutKind::HorizontalStack))
-},
-{ { XKB_KEY_y, MODKEY | CTRL },
- CALL(set_layout(LayoutHandler::LayoutKind::CompactHorizontalStack))
-},
-{ { XKB_KEY_V, MODKEY | SHIFT },
- CALL(set_layout(LayoutHandler::LayoutKind::VerticalStack))
-},
-{ { XKB_KEY_V, MODKEY | CTRL },
- CALL(set_layout(LayoutHandler::LayoutKind::CompactVerticalStack))
-},
-{ { XKB_KEY_F, MODKEY | CTRL | SHIFT },
- CALL(set_layout_retain_region(LayoutHandler::LayoutKind::Float))
-},
-{ { XKB_KEY_space, MODKEY },
- CALL(toggle_layout())
-},
-{ { XKB_KEY_Return, MODKEY },
- CALL_EXTERNAL(alacritty)
-},
-
-// workspace layout data modifiers
-{ { XKB_KEY_equal, MODKEY },
- CALL(change_gap_size(2))
-},
-{ { XKB_KEY_minus, MODKEY },
- CALL(change_gap_size(-2))
-},
-{ { XKB_KEY_equal, MODKEY | SHIFT },
- CALL(reset_gap_size())
-},
-{ { XKB_KEY_i, MODKEY },
- CALL(change_main_count(1))
-},
-{ { XKB_KEY_d, MODKEY },
- CALL(change_main_count(-1))
-},
-{ { XKB_KEY_l, MODKEY },
- CALL(change_main_factor(.05f))
-},
-{ { XKB_KEY_h, MODKEY },
- CALL(change_main_factor(-.05f))
-},
-{ { XKB_KEY_Page_Up, MODKEY | SHIFT },
- CALL(change_margin(5))
-},
-{ { XKB_KEY_Page_Down, MODKEY | SHIFT },
- CALL(change_margin(-5))
-},
-{ { XKB_KEY_Left, MODKEY | SHIFT },
- CALL(change_margin(Edge::Left, 5))
-},
-{ { XKB_KEY_Left, MODKEY | CTRL | SHIFT },
- CALL(change_margin(Edge::Left, -5))
-},
-{ { XKB_KEY_Up, MODKEY | SHIFT },
- CALL(change_margin(Edge::Top, 5))
-},
-{ { XKB_KEY_Up, MODKEY | CTRL | SHIFT },
- CALL(change_margin(Edge::Top, -5))
-},
-{ { XKB_KEY_Right, MODKEY | SHIFT },
- CALL(change_margin(Edge::Right, 5))
-},
-{ { XKB_KEY_Right, MODKEY | CTRL | SHIFT },
- CALL(change_margin(Edge::Right, -5))
-},
-{ { XKB_KEY_Down, MODKEY | SHIFT },
- CALL(change_margin(Edge::Bottom, 5))
-},
-{ { XKB_KEY_Down, MODKEY | CTRL | SHIFT },
- CALL(change_margin(Edge::Bottom, -5))
-},
-{ { XKB_KEY_comma, MODKEY | CTRL | SHIFT },
- CALL(cycle_layout_data(Direction::Backward))
-},
-{ { XKB_KEY_period, MODKEY | CTRL | SHIFT },
- CALL(cycle_layout_data(Direction::Forward))
-},
-{ { XKB_KEY_slash, MODKEY | CTRL | SHIFT },
- CALL(toggle_layout_data())
-},
-{ { XKB_KEY_Delete, MODKEY | CTRL | SHIFT },
- CALL(copy_data_from_prev_layout())
-},
-{ { XKB_KEY_equal, MODKEY | CTRL | SHIFT },
- CALL(reset_margin())
-},
-{ { XKB_KEY_equal, MODKEY | SECKEY | CTRL | SHIFT },
- CALL(reset_layout_data())
-},
-};
-
-}
-#undef CALL_EXTERNAL
-#undef CALL
-#undef MOD5
-#undef LOGO
-#undef MOD3
-#undef MOD2
-#undef ALT
-#undef CTRL
-#undef CAPS
-#undef SHIFT
-#undef SECKEY
-#undef MODKEY
diff --git a/include/kranewl/input/mouse.hh b/include/kranewl/input/mouse.hh
@@ -1,104 +0,0 @@
-#pragma once
-
-#include <kranewl/geometry.hh>
-
-extern "C" {
-#include <wlr/backend.h>
-#include <xkbcommon/xkbcommon.h>
-}
-
-#include <cstdint>
-#include <unordered_set>
-
-struct MouseInput {
- unsigned button;
- uint32_t modifiers;
-};
-
-typedef class Server* Server_ptr;
-typedef class Seat* Seat_ptr;
-typedef struct View* View_ptr;
-
-typedef struct Mouse {
- enum class CursorMode {
- Passthrough,
- Move,
- Resize,
- };
-
- enum class CursorButton {
- Left = 272,
- Right = 273,
- Middle = 274,
- };
-
- Mouse(
- Server_ptr,
- Seat_ptr,
- struct wlr_cursor*,
- struct wlr_pointer_constraints_v1*,
- struct wlr_relative_pointer_manager_v1*,
- struct wlr_virtual_pointer_manager_v1*
- );
- ~Mouse();
-
- View_ptr view_under_cursor() const;
-
- static void handle_cursor_motion(struct wl_listener*, void*);
- static void handle_cursor_motion_absolute(struct wl_listener*, void*);
- static void handle_cursor_button(struct wl_listener*, void*);
- static void handle_cursor_axis(struct wl_listener*, void*);
- static void handle_cursor_frame(struct wl_listener*, void*);
- static void handle_request_start_drag(struct wl_listener*, void*);
- static void handle_start_drag(struct wl_listener*, void*);
- static void handle_request_set_cursor(struct wl_listener*, void*);
-
- Server_ptr mp_server;
- Seat_ptr mp_seat;
-
- CursorMode m_cursor_mode;
- struct wlr_cursor* mp_cursor;
- 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;
-
- struct {
- View_ptr client;
- double x, y;
- Region region;
- uint32_t resize_edges;
- } m_grab_state;
-
- struct wl_listener ml_cursor_motion;
- struct wl_listener ml_cursor_motion_absolute;
- struct wl_listener ml_cursor_button;
- struct wl_listener ml_cursor_axis;
- struct wl_listener ml_cursor_frame;
- struct wl_listener ml_request_start_drag;
- struct wl_listener ml_start_drag;
- struct wl_listener ml_request_set_cursor;
-
-}* Mouse_ptr;
-
-inline bool
-operator==(MouseInput const& lhs, MouseInput const& rhs)
-{
- return lhs.button == rhs.button
- && lhs.modifiers == rhs.modifiers;
-}
-
-namespace std
-{
- template <>
- struct hash<MouseInput> {
- std::size_t
- operator()(MouseInput const& input) const
- {
- std::size_t modifiers_hash = std::hash<uint32_t>()(input.modifiers);
- std::size_t button_hash = std::hash<unsigned>()(input.button);
-
- return modifiers_hash ^ button_hash;
- }
- };
-}
diff --git a/include/kranewl/input/mousebindings.hh b/include/kranewl/input/mousebindings.hh
@@ -1,3 +0,0 @@
-#pragma once
-
-
diff --git a/include/kranewl/input/seat.hh b/include/kranewl/input/seat.hh
@@ -13,7 +13,7 @@ extern "C" {
typedef class Server* Server_ptr;
typedef class Model* Model_ptr;
typedef struct Keyboard* Keyboard_ptr;
-typedef struct Mouse* Mouse_ptr;
+typedef struct Cursor* Cursor_ptr;
typedef class Seat final {
public:
@@ -55,11 +55,9 @@ public:
struct wlr_virtual_keyboard_manager_v1* mp_virtual_keyboard_manager;
struct wlr_keyboard_shortcuts_inhibit_manager_v1* mp_keyboard_shortcuts_inhibit_manager;
- Mouse_ptr mp_mouse;
+ Cursor_ptr mp_cursor;
std::vector<Keyboard_ptr> m_keyboards;
- struct wl_client* mp_exclusive_client;
-
struct wl_listener ml_destroy;
struct wl_listener ml_request_set_selection;
struct wl_listener ml_request_set_primary_selection;
diff --git a/include/kranewl/layer.hh b/include/kranewl/layer.hh
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <cstdlib>
+
+enum Layer : short {
+ None = -1,
+ Background = 0,
+ Bottom = 1,
+ Tile = 2,
+ Free = 3,
+ Top = 4,
+ Overlay = 5,
+ NoFocus = 6,
+};
diff --git a/include/kranewl/layers.hh b/include/kranewl/layers.hh
@@ -1,13 +0,0 @@
-#pragma once
-
-struct Layer {
- typedef short type;
- static constexpr short None = -1;
- static constexpr short Background = 0;
- static constexpr short Bottom = 1;
- static constexpr short Tile = 2;
- static constexpr short Free = 3;
- static constexpr short Top = 4;
- static constexpr short Overlay = 5;
- static constexpr short NoFocus = 6;
-};
diff --git a/include/kranewl/model.hh b/include/kranewl/model.hh
@@ -37,9 +37,10 @@ public:
void register_server(Server_ptr);
void exit();
- const View_ptr focused_view() const;
+ View_ptr focused_view() const;
KeyBindings const& key_bindings() const;
+ CursorBindings const& cursor_bindings() const;
Output_ptr create_output(struct wlr_output*, struct wlr_scene_output*, Region const&&);
void register_output(Output_ptr);
@@ -60,7 +61,6 @@ public:
void disown_view(View_ptr);
void reclaim_view(View_ptr);
void focus_view(View_ptr);
- void unfocus_view(View_ptr);
void place_view(Placement&);
void sync_focus();
@@ -174,6 +174,6 @@ private:
View_ptr mp_focus;
const KeyBindings m_key_bindings;
- const MouseBindings m_mouse_bindings;
+ const CursorBindings m_cursor_bindings;
};
diff --git a/include/kranewl/server.hh b/include/kranewl/server.hh
@@ -2,6 +2,7 @@
#include <kranewl/geometry.hh>
#include <kranewl/input/seat.hh>
+#include <kranewl/layer.hh>
extern "C" {
#include <wlr/backend.h>
@@ -9,6 +10,7 @@ extern "C" {
#include <xkbcommon/xkbcommon.h>
}
+#include <array>
#include <cstdint>
#include <string>
@@ -17,12 +19,6 @@ typedef class Server* Server_ptr;
typedef struct View* View_ptr;
typedef class Server final {
- enum class CursorMode {
- Passthrough,
- Move,
- Resize,
- };
-
public:
Server(Model_ptr);
~Server();
@@ -47,7 +43,6 @@ private:
static void handle_xdg_toplevel_destroy(struct wl_listener*, void*);
static void handle_xdg_toplevel_request_move(struct wl_listener*, void*);
static void handle_xdg_toplevel_request_resize(struct wl_listener*, void*);
- static void handle_xdg_toplevel_handle_moveresize(View_ptr, CursorMode, uint32_t);
#ifdef XWAYLAND
static void handle_xwayland_ready(struct wl_listener*, void*);
static void handle_new_xwayland_surface(struct wl_listener*, void*);
@@ -66,17 +61,15 @@ public:
struct wlr_renderer* mp_renderer;
struct wlr_allocator* mp_allocator;
struct wlr_compositor* mp_compositor;
- struct wlr_data_device_manager* mp_data_device_manager;
- struct wlr_output_layout* mp_output_layout;
- struct wlr_scene* mp_scene;
- struct wlr_scene_node* m_layers[7];
#ifdef XWAYLAND
struct wlr_xwayland* mp_xwayland;
#endif
-
+ struct wlr_data_device_manager* mp_data_device_manager;
+ struct wlr_output_layout* mp_output_layout;
+ struct wlr_scene* mp_scene;
+ std::array<struct wlr_scene_node*, 7> m_layers;
Seat m_seat;
-
private:
struct wlr_xdg_shell* mp_xdg_shell;
struct wlr_layer_shell_v1* mp_layer_shell;
diff --git a/include/kranewl/tree/client.hh b/include/kranewl/tree/client.hh
@@ -1,185 +0,0 @@
-#pragma once
-
-#include <kranewl/common.hh>
-#include <kranewl/decoration.hh>
-#include <kranewl/geometry.hh>
-#include <kranewl/tree/surface.hh>
-
-extern "C" {
-#include <wlr/backend.h>
-}
-
-#include <chrono>
-#include <cstdint>
-#include <optional>
-#include <string>
-#include <vector>
-
-typedef class Server* Server_ptr;
-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};
-
- enum class OutsideState {
- Focused,
- FocusedDisowned,
- FocusedSticky,
- Unfocused,
- UnfocusedDisowned,
- UnfocusedSticky,
- Urgent
- };
-
- static bool
- is_free(Client_ptr client)
- {
- return (client->m_floating && (!client->m_fullscreen || client->m_contained))
- || !client->m_managed
- || client->m_disowned;
- }
-
- Client(
- Server_ptr server,
- Surface surface,
- Output_ptr output,
- Context_ptr context,
- Workspace_ptr workspace
- );
-
- ~Client();
-
- Client(Client const&) = default;
- Client& operator=(Client const&) = default;
-
- OutsideState get_outside_state() const noexcept;
-
- struct wlr_surface* get_surface() noexcept;
-
- void focus() noexcept;
- void unfocus() noexcept;
-
- void stick() noexcept;
- void unstick() noexcept;
-
- void disown() noexcept;
- void reclaim() noexcept;
-
- void set_urgent() noexcept;
- void unset_urgent() noexcept;
-
- void expect_unmap() noexcept;
- bool consume_unmap_if_expecting() noexcept;
-
- void set_tile_region(Region&) noexcept;
- void set_free_region(Region&) noexcept;
-
- void set_tile_decoration(Decoration const&) noexcept;
- void set_free_decoration(Decoration const&) noexcept;
-
- Server_ptr mp_server;
-
- Uid m_uid;
- Surface m_surface;
-
- 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;
-
- Output_ptr mp_output;
- Context_ptr mp_context;
- Workspace_ptr mp_workspace;
-
- Region m_free_region;
- Region m_tile_region;
- Region m_active_region;
- Region m_previous_region;
- Region m_inner_region;
-
- Decoration m_tile_decoration;
- Decoration m_free_decoration;
- Decoration m_active_decoration;
-
- bool m_focused;
- bool m_mapped;
- bool m_managed;
- bool m_urgent;
- bool m_floating;
- bool m_fullscreen;
- bool m_contained;
- bool m_invincible;
- bool m_sticky;
- bool m_iconifyable;
- bool m_iconified;
- bool m_disowned;
- bool m_producing;
- bool m_attaching;
-
- std::chrono::time_point<std::chrono::steady_clock> m_last_focused;
- std::chrono::time_point<std::chrono::steady_clock> m_last_touched;
- std::chrono::time_point<std::chrono::steady_clock> m_managed_since;
-
- struct wl_listener ml_commit;
- struct wl_listener ml_map;
- struct wl_listener ml_unmap;
- struct wl_listener ml_destroy;
- struct wl_listener ml_set_title;
- struct wl_listener ml_fullscreen;
- struct wl_listener ml_request_move;
- struct wl_listener ml_request_resize;
-#ifdef XWAYLAND
- struct wl_listener ml_request_activate;
- struct wl_listener ml_request_configure;
- struct wl_listener ml_set_hints;
-#else
- struct wl_listener ml_new_xdg_popup;
-#endif
-
-private:
- OutsideState m_outside_state;
-
- void set_inner_region(Region&) noexcept;
- void set_active_region(Region&) noexcept;
-
-}* Client_ptr;
-
-inline bool
-operator==(Client const& lhs, Client const& rhs)
-{
- if (lhs.m_surface.type != rhs.m_surface.type)
- return false;
-
- switch (lhs.m_surface.type) {
- case SurfaceType::XDGShell: // fallthrough
- case SurfaceType::LayerShell: return lhs.m_surface.xdg == rhs.m_surface.xdg;
- case SurfaceType::X11Managed: // fallthrough
- case SurfaceType::X11Unmanaged: return lhs.m_surface.xwayland == rhs.m_surface.xwayland;
- }
-}
-
-namespace std
-{
- template <>
- struct hash<Client> {
-
- std::size_t
- operator()(Client const& client) const
- {
- switch (client.m_surface.type) {
- case SurfaceType::XDGShell: // fallthrough
- case SurfaceType::LayerShell:
- return std::hash<wlr_xdg_surface*>{}(client.m_surface.xdg);
- case SurfaceType::X11Managed: // fallthrough
- case SurfaceType::X11Unmanaged:
- return std::hash<wlr_xwayland_surface*>{}(client.m_surface.xwayland);
- }
- }
-
- };
-}
diff --git a/include/kranewl/tree/output.hh b/include/kranewl/tree/output.hh
@@ -52,10 +52,6 @@ public:
struct wlr_output* mp_wlr_output;
struct wlr_scene_output* mp_wlr_scene_output;
- struct wlr_output_damage* mp_damage;
- struct wlr_output_mode* mp_current_mode;
- enum wl_output_subpixel m_subpixel;
-
struct wl_listener ml_frame;
struct wl_listener ml_commit;
struct wl_listener ml_present;
diff --git a/include/kranewl/tree/view.hh b/include/kranewl/tree/view.hh
@@ -3,7 +3,7 @@
#include <kranewl/common.hh>
#include <kranewl/decoration.hh>
#include <kranewl/geometry.hh>
-#include <kranewl/layers.hh>
+#include <kranewl/layer.hh>
#include <kranewl/model.hh>
#include <kranewl/tree/surface.hh>
@@ -88,7 +88,7 @@ typedef struct View {
void map();
void unmap();
void tile(Toggle);
- void relayer(Layer::type);
+ void relayer(Layer);
void raise() const;
void lower() const;
@@ -129,6 +129,7 @@ typedef struct View {
Region const& tile_region() const { return m_tile_region; }
Region const& active_region() const { return m_active_region; }
void set_free_region(Region const&);
+ void set_free_pos(Pos const&);
void set_tile_region(Region const&);
Dim const& minimum_dim() const { return m_minimum_dim; }
Dim const& preferred_dim() const { return m_preferred_dim; }
@@ -216,12 +217,13 @@ private:
bool m_iconified;
bool m_disowned;
- Layer::type m_layer;
+ Layer m_layer;
OutsideState m_outside_state;
void set_inner_region(Region const&);
void set_active_region(Region const&);
+ void set_active_pos(Pos const&);
}* View_ptr;
diff --git a/src/kranewl/input/cursor.cc b/src/kranewl/input/cursor.cc
@@ -0,0 +1,420 @@
+#include <trace.hh>
+
+#include <kranewl/input/cursor.hh>
+
+#include <kranewl/input/seat.hh>
+#include <kranewl/layer.hh>
+#include <kranewl/server.hh>
+#include <kranewl/tree/view.hh>
+#include <kranewl/util.hh>
+
+// https://github.com/swaywm/wlroots/issues/682
+#include <pthread.h>
+#define class class_
+#define namespace namespace_
+#define static
+extern "C" {
+#include <wlr/types/wlr_cursor.h>
+#include <wlr/types/wlr_data_device.h>
+#include <wlr/types/wlr_idle.h>
+#include <wlr/types/wlr_scene.h>
+#include <wlr/types/wlr_seat.h>
+#include <wlr/types/wlr_xcursor_manager.h>
+}
+#undef static
+#undef class
+#undef namespace
+
+Cursor::Cursor(
+ Server_ptr server,
+ Seat_ptr seat,
+ struct wlr_cursor* cursor,
+ struct wlr_pointer_constraints_v1* pointer_constraints,
+ struct wlr_relative_pointer_manager_v1* relative_pointer_manager,
+ struct wlr_virtual_pointer_manager_v1* virtual_pointer_manager
+)
+ : mp_server(server),
+ mp_seat(seat),
+ mp_wlr_cursor(cursor),
+ mp_cursor_manager(wlr_xcursor_manager_create(nullptr, 24)),
+ mp_pointer_constraints(pointer_constraints),
+ mp_relative_pointer_manager(relative_pointer_manager),
+ mp_virtual_pointer_manager(virtual_pointer_manager),
+ ml_cursor_motion({ .notify = Cursor::handle_cursor_motion }),
+ ml_cursor_motion_absolute({ .notify = Cursor::handle_cursor_motion_absolute }),
+ ml_cursor_button({ .notify = Cursor::handle_cursor_button }),
+ ml_cursor_axis({ .notify = Cursor::handle_cursor_axis }),
+ ml_cursor_frame({ .notify = Cursor::handle_cursor_frame }),
+ ml_request_start_drag({ .notify = Cursor::handle_request_start_drag }),
+ ml_start_drag({ .notify = Cursor::handle_start_drag }),
+ ml_request_set_cursor({ .notify = Cursor::handle_request_set_cursor })
+{
+ TRACE();
+
+ wlr_xcursor_manager_load(mp_cursor_manager, 1);
+
+ wl_signal_add(&cursor->events.motion, &ml_cursor_motion);
+ wl_signal_add(&cursor->events.motion_absolute, &ml_cursor_motion_absolute);
+ wl_signal_add(&cursor->events.button, &ml_cursor_button);
+ wl_signal_add(&cursor->events.axis, &ml_cursor_axis);
+ wl_signal_add(&cursor->events.frame, &ml_cursor_frame);
+ wl_signal_add(&mp_seat->mp_wlr_seat->events.request_start_drag, &ml_request_start_drag);
+ wl_signal_add(&mp_seat->mp_wlr_seat->events.start_drag, &ml_start_drag);
+ wl_signal_add(&mp_seat->mp_wlr_seat->events.request_set_cursor, &ml_request_set_cursor);
+}
+
+Cursor::~Cursor()
+{
+ TRACE();
+
+}
+
+static inline View_ptr
+view_at(
+ Server_ptr server,
+ double lx, double ly,
+ struct wlr_surface** surface,
+ double* sx, double* sy
+)
+{
+ static std::vector<Layer> focus_order = {
+ Layer::Overlay,
+ Layer::Top,
+ Layer::Free,
+ Layer::Tile,
+ Layer::Bottom,
+ };
+
+ struct wlr_scene_node* node;
+ for (auto const& layer : focus_order) {
+ if ((node = wlr_scene_node_at(server->m_layers[layer], lx, ly, sx, sy))) {
+ if (node->type != WLR_SCENE_NODE_SURFACE)
+ return nullptr;
+
+ *surface = wlr_scene_surface_from_node(node)->surface;
+
+ while (node && !node->data)
+ node = node->parent;
+
+ return reinterpret_cast<View_ptr>(node->data);
+ }
+ }
+
+ return nullptr;
+}
+
+View_ptr
+Cursor::view_under_cursor() const
+{
+ double sx, sy;
+ struct wlr_surface* surface = nullptr;
+
+ View_ptr view = view_at(
+ mp_server,
+ mp_wlr_cursor->x,
+ mp_wlr_cursor->y,
+ &surface,
+ &sx, &sy
+ );
+
+ return view;
+}
+
+static inline void
+process_cursor_move(Cursor_ptr cursor, uint32_t time)
+{
+ TRACE();
+
+ View_ptr view = cursor->m_grab_state.view;
+ view->set_free_pos(Pos{
+ .x = cursor->mp_wlr_cursor->x - cursor->m_grab_state.x,
+ .y = cursor->mp_wlr_cursor->y - cursor->m_grab_state.y
+ });
+
+ view->configure(
+ view->free_region(),
+ view->free_decoration().extents(),
+ true
+ );
+}
+
+static inline void
+process_cursor_resize(Cursor_ptr cursor, uint32_t time)
+{
+ TRACE();
+
+}
+
+static inline void
+cursor_motion_to_client(
+ Cursor_ptr cursor,
+ View_ptr view,
+ struct wlr_surface* surface,
+ double sx, double sy,
+ uint32_t time
+)
+{
+ if (true /* TODO: focus_follows_cursor */ && time && view && view->managed())
+ cursor->mp_seat->mp_model->focus_view(view);
+
+ if (!surface) {
+ wlr_seat_pointer_notify_clear_focus(cursor->mp_seat->mp_wlr_seat);
+ return;
+ }
+
+ if (!time) {
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ time = now.tv_sec * 1000 + now.tv_nsec / 1000000;
+ }
+
+ wlr_seat_pointer_notify_enter(cursor->mp_seat->mp_wlr_seat, surface, sx, sy);
+ wlr_seat_pointer_notify_motion(cursor->mp_seat->mp_wlr_seat, time, sx, sy);
+}
+
+static inline void
+process_cursor_motion(Cursor_ptr cursor, uint32_t time)
+{
+ TRACE();
+
+ struct wlr_drag_icon* icon;
+ if (cursor->mp_seat->mp_wlr_seat->drag && (icon = cursor->mp_seat->mp_wlr_seat->drag->icon))
+ wlr_scene_node_set_position(
+ reinterpret_cast<struct wlr_scene_node*>(icon->data),
+ cursor->mp_wlr_cursor->x + icon->surface->sx,
+ cursor->mp_wlr_cursor->y + icon->surface->sy
+ );
+
+ switch (cursor->m_cursor_mode) {
+ case Cursor::CursorMode::Move: process_cursor_move(cursor, time); return;
+ case Cursor::CursorMode::Resize: process_cursor_resize(cursor, time); return;
+ case Cursor::CursorMode::Passthrough: // fallthrough
+ default: break;
+ }
+
+ double sx, sy;
+ struct wlr_surface* surface = nullptr;
+
+ View_ptr view = view_at(
+ cursor->mp_server,
+ cursor->mp_wlr_cursor->x,
+ cursor->mp_wlr_cursor->y,
+ &surface,
+ &sx, &sy
+ );
+
+ if (!view && time) {
+ wlr_xcursor_manager_set_cursor_image(
+ cursor->mp_cursor_manager,
+ "left_ptr",
+ cursor->mp_wlr_cursor
+ );
+ }
+
+ cursor_motion_to_client(cursor, view, surface, sx, sy, time);
+}
+
+void
+Cursor::handle_cursor_motion(struct wl_listener* listener, void* data)
+{
+ TRACE();
+
+ Cursor_ptr cursor = wl_container_of(listener, cursor, ml_cursor_motion);
+ struct wlr_event_pointer_motion* event
+ = reinterpret_cast<struct wlr_event_pointer_motion*>(data);
+
+ wlr_cursor_move(cursor->mp_wlr_cursor, event->device, event->delta_x, event->delta_y);
+ process_cursor_motion(cursor, event->time_msec);
+}
+
+void
+Cursor::handle_cursor_motion_absolute(struct wl_listener* listener, void* data)
+{
+ TRACE();
+
+ Cursor_ptr cursor = wl_container_of(listener, cursor, ml_cursor_motion_absolute);
+ struct wlr_event_pointer_motion_absolute* event
+ = reinterpret_cast<struct wlr_event_pointer_motion_absolute*>(data);
+
+ wlr_cursor_warp_absolute(cursor->mp_wlr_cursor, event->device, event->x, event->y);
+ process_cursor_motion(cursor, event->time_msec);
+}
+
+bool
+process_cursorbinding(Cursor_ptr cursor, uint32_t button, uint32_t modifiers)
+{
+ TRACE();
+
+ if (!button || !modifiers)
+ return false;
+
+ CursorInput input = CursorInput{
+ .target = CursorInput::Target::Global,
+ .button = static_cast<CursorInput::Button>(button),
+ .modifiers = modifiers & ~WLR_MODIFIER_CAPS
+ };
+
+ View_ptr view = cursor->view_under_cursor();
+ Model_ptr model = cursor->mp_seat->mp_model;
+ View_ptr focused_view = model->focused_view();
+
+#define CALL_AND_HANDLE_FOCUS(binding) \
+ do { \
+ if (((*binding)(*model, view) && view && view != focused_view && view->managed())) \
+ model->focus_view(view); \
+ } while (false)
+
+ { // global binding
+ auto binding = Util::const_retrieve(model->cursor_bindings(), input);
+
+ if (binding) {
+ CALL_AND_HANDLE_FOCUS(binding);
+ return true;
+ }
+ }
+
+ if (!view) { // root binding
+ input.target = CursorInput::Target::Root;
+ auto binding = Util::const_retrieve(model->cursor_bindings(), input);
+
+ if (binding) {
+ CALL_AND_HANDLE_FOCUS(binding);
+ return true;
+ }
+ } else { // view binding
+ input.target = CursorInput::Target::View;
+ auto binding = Util::const_retrieve(model->cursor_bindings(), input);
+
+ if (binding) {
+ CALL_AND_HANDLE_FOCUS(binding);
+ return true;
+ }
+ }
+#undef CALL_AND_HANDLE_FOCUS
+
+ return false;
+}
+
+void
+Cursor::handle_cursor_button(struct wl_listener* listener, void* data)
+{
+ TRACE();
+
+ Cursor_ptr cursor = wl_container_of(listener, cursor, ml_cursor_button);
+ struct wlr_event_pointer_button* event
+ = reinterpret_cast<struct wlr_event_pointer_button*>(data);
+
+ wlr_idle_notify_activity(
+ cursor->mp_seat->mp_idle,
+ cursor->mp_seat->mp_wlr_seat
+ );
+
+ switch (event->state) {
+ case WLR_BUTTON_PRESSED:
+ {
+ struct wlr_keyboard* keyboard
+ = wlr_seat_get_keyboard(cursor->mp_seat->mp_wlr_seat);
+
+ uint32_t button = event->button;
+ uint32_t modifiers = keyboard
+ ? wlr_keyboard_get_modifiers(keyboard)
+ : 0;
+
+ if (!process_cursorbinding(cursor, button, modifiers) && false /* TODO: !focus_follows_cursor */) {
+ View_ptr view = cursor->view_under_cursor();
+
+ if (view && !view->focused() && view->managed()) {
+ cursor->mp_seat->mp_model->focus_view(view);
+ return;
+ }
+ }
+
+ break;
+ }
+ case WLR_BUTTON_RELEASED:
+ {
+ if (cursor->m_cursor_mode != CursorMode::Passthrough) {
+ cursor->m_cursor_mode = CursorMode::Passthrough;
+
+ wlr_xcursor_manager_set_cursor_image(
+ cursor->mp_cursor_manager,
+ "left_ptr",
+ cursor->mp_wlr_cursor
+ );
+ }
+
+ break;
+ }
+ default: break;
+ }
+
+ wlr_seat_pointer_notify_button(
+ cursor->mp_seat->mp_wlr_seat,
+ event->time_msec,
+ event->button,
+ event->state
+ );
+}
+
+void
+Cursor::handle_cursor_axis(struct wl_listener* listener, void* data)
+{
+ TRACE();
+
+ Cursor_ptr cursor = wl_container_of(listener, cursor, ml_cursor_axis);
+ struct wlr_event_pointer_axis* event
+ = reinterpret_cast<struct wlr_event_pointer_axis*>(data);
+
+ wlr_seat_pointer_notify_axis(
+ cursor->mp_seat->mp_wlr_seat,
+ event->time_msec,
+ event->orientation,
+ event->delta,
+ event->delta_discrete,
+ event->source
+ );
+}
+
+void
+Cursor::handle_cursor_frame(struct wl_listener* listener, void*)
+{
+ TRACE();
+
+ Cursor_ptr cursor = wl_container_of(listener, cursor, ml_cursor_frame);
+ wlr_seat_pointer_notify_frame(cursor->mp_seat->mp_wlr_seat);
+}
+
+void
+Cursor::handle_request_start_drag(struct wl_listener* listener, void* data)
+{
+ TRACE();
+
+ Cursor_ptr cursor = wl_container_of(listener, cursor, ml_request_set_cursor);
+ struct wlr_seat_pointer_request_set_cursor_event* event
+ = reinterpret_cast<struct wlr_seat_pointer_request_set_cursor_event*>(data);
+
+ struct wlr_seat_client* focused_client
+ = cursor->mp_seat->mp_wlr_seat->pointer_state.focused_client;
+
+ if (focused_client == event->seat_client)
+ wlr_cursor_set_surface(
+ cursor->mp_wlr_cursor,
+ event->surface,
+ event->hotspot_x,
+ event->hotspot_y
+ );
+}
+
+void
+Cursor::handle_start_drag(struct wl_listener*, void*)
+{
+ TRACE();
+
+}
+
+void
+Cursor::handle_request_set_cursor(struct wl_listener*, void*)
+{
+ TRACE();
+
+}
diff --git a/src/kranewl/input/mouse.cc b/src/kranewl/input/mouse.cc
@@ -1,300 +0,0 @@
-#include <trace.hh>
-
-#include <kranewl/input/mouse.hh>
-
-#include <kranewl/input/seat.hh>
-#include <kranewl/layers.hh>
-#include <kranewl/server.hh>
-#include <kranewl/tree/view.hh>
-
-// https://github.com/swaywm/wlroots/issues/682
-#include <pthread.h>
-#define class class_
-#define namespace namespace_
-#define static
-extern "C" {
-#include <wlr/types/wlr_cursor.h>
-#include <wlr/types/wlr_data_device.h>
-#include <wlr/types/wlr_scene.h>
-#include <wlr/types/wlr_seat.h>
-#include <wlr/types/wlr_xcursor_manager.h>
-}
-#undef static
-#undef class
-#undef namespace
-
-Mouse::Mouse(
- Server_ptr server,
- Seat_ptr seat,
- struct wlr_cursor* cursor,
- struct wlr_pointer_constraints_v1* pointer_constraints,
- struct wlr_relative_pointer_manager_v1* relative_pointer_manager,
- struct wlr_virtual_pointer_manager_v1* virtual_pointer_manager
-)
- : mp_server(server),
- mp_seat(seat),
- mp_cursor(cursor),
- mp_cursor_manager(wlr_xcursor_manager_create(nullptr, 24)),
- mp_pointer_constraints(pointer_constraints),
- mp_relative_pointer_manager(relative_pointer_manager),
- mp_virtual_pointer_manager(virtual_pointer_manager),
- ml_cursor_motion({ .notify = Mouse::handle_cursor_motion }),
- ml_cursor_motion_absolute({ .notify = Mouse::handle_cursor_motion_absolute }),
- ml_cursor_button({ .notify = Mouse::handle_cursor_button }),
- ml_cursor_axis({ .notify = Mouse::handle_cursor_axis }),
- ml_cursor_frame({ .notify = Mouse::handle_cursor_frame }),
- ml_request_start_drag({ .notify = Mouse::handle_request_start_drag }),
- ml_start_drag({ .notify = Mouse::handle_start_drag }),
- ml_request_set_cursor({ .notify = Mouse::handle_request_set_cursor })
-{
- TRACE();
-
- wlr_xcursor_manager_load(mp_cursor_manager, 1);
-
- wl_signal_add(&cursor->events.motion, &ml_cursor_motion);
- wl_signal_add(&cursor->events.motion_absolute, &ml_cursor_motion_absolute);
- wl_signal_add(&cursor->events.button, &ml_cursor_button);
- wl_signal_add(&cursor->events.axis, &ml_cursor_axis);
- wl_signal_add(&cursor->events.frame, &ml_cursor_frame);
- wl_signal_add(&mp_seat->mp_wlr_seat->events.request_start_drag, &ml_request_start_drag);
- wl_signal_add(&mp_seat->mp_wlr_seat->events.start_drag, &ml_start_drag);
- wl_signal_add(&mp_seat->mp_wlr_seat->events.request_set_cursor, &ml_request_set_cursor);
-}
-
-Mouse::~Mouse()
-{
- TRACE();
-
-}
-
-static inline View_ptr
-view_at(
- Server_ptr server,
- double lx, double ly,
- struct wlr_surface** surface,
- double* sx, double* sy
-)
-{
- static std::vector<Layer::type> focus_order = {
- Layer::Overlay,
- Layer::Top,
- Layer::Free,
- Layer::Tile,
- Layer::Bottom,
- };
-
- struct wlr_scene_node** layers = server->m_layers;
- struct wlr_scene_node* node;
-
- for (auto const& layer : focus_order) {
- if ((node = wlr_scene_node_at(layers[layer], lx, ly, sx, sy))) {
- if (node->type != WLR_SCENE_NODE_SURFACE)
- return nullptr;
-
- *surface = wlr_scene_surface_from_node(node)->surface;
-
- while (node && !node->data)
- node = node->parent;
-
- return reinterpret_cast<View_ptr>(node->data);
- }
- }
-
- return nullptr;
-}
-
-View_ptr
-Mouse::view_under_cursor() const
-{
- double sx, sy;
- struct wlr_surface* surface = nullptr;
-
- View_ptr view = view_at(
- mp_server,
- mp_cursor->x,
- mp_cursor->y,
- &surface,
- &sx, &sy
- );
-
- return view;
-}
-
-static inline void
-process_cursor_move(Mouse_ptr mouse, uint32_t time)
-{
- TRACE();
-
-}
-
-static inline void
-process_cursor_resize(Mouse_ptr mouse, uint32_t time)
-{
- TRACE();
-
-}
-
-static inline void
-cursor_motion_to_client(
- Mouse_ptr mouse,
- View_ptr view,
- struct wlr_surface* surface,
- double sx, double sy,
- uint32_t time
-)
-{
- if (true /* TODO: focus_follows_mouse */ && time && view && view->managed())
- mouse->mp_seat->mp_model->focus_view(view);
-
- if (!surface) {
- wlr_seat_pointer_notify_clear_focus(mouse->mp_seat->mp_wlr_seat);
- return;
- }
-
- if (!time) {
- struct timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- time = now.tv_sec * 1000 + now.tv_nsec / 1000000;
- }
-
- wlr_seat_pointer_notify_enter(mouse->mp_seat->mp_wlr_seat, surface, sx, sy);
- wlr_seat_pointer_notify_motion(mouse->mp_seat->mp_wlr_seat, time, sx, sy);
-}
-
-static inline void
-process_cursor_motion(Mouse_ptr mouse, uint32_t time)
-{
- TRACE();
-
- struct wlr_drag_icon* icon;
- if (mouse->mp_seat->mp_wlr_seat->drag && (icon = mouse->mp_seat->mp_wlr_seat->drag->icon))
- wlr_scene_node_set_position(
- reinterpret_cast<struct wlr_scene_node*>(icon->data),
- mouse->mp_cursor->x + icon->surface->sx,
- mouse->mp_cursor->y + icon->surface->sy
- );
-
- switch (mouse->m_cursor_mode) {
- case Mouse::CursorMode::Move: process_cursor_move(mouse, time); return;
- case Mouse::CursorMode::Resize: process_cursor_resize(mouse, time); return;
- case Mouse::CursorMode::Passthrough: // fallthrough
- default: break;
- }
-
- double sx, sy;
- struct wlr_surface* surface = nullptr;
-
- View_ptr view = view_at(
- mouse->mp_server,
- mouse->mp_cursor->x,
- mouse->mp_cursor->y,
- &surface,
- &sx, &sy
- );
-
- if (!view && time) {
- wlr_xcursor_manager_set_cursor_image(
- mouse->mp_cursor_manager,
- "left_ptr",
- mouse->mp_cursor
- );
- }
-
- cursor_motion_to_client(mouse, view, surface, sx, sy, time);
-}
-
-void
-Mouse::handle_cursor_motion(struct wl_listener* listener, void* data)
-{
- TRACE();
-
- Mouse_ptr mouse = wl_container_of(listener, mouse, ml_cursor_motion);
- struct wlr_event_pointer_motion* event
- = reinterpret_cast<struct wlr_event_pointer_motion*>(data);
-
- wlr_cursor_move(mouse->mp_cursor, event->device, event->delta_x, event->delta_y);
- process_cursor_motion(mouse, event->time_msec);
-}
-
-void
-Mouse::handle_cursor_motion_absolute(struct wl_listener* listener, void* data)
-{
- TRACE();
-
- Mouse_ptr mouse = wl_container_of(listener, mouse, ml_cursor_motion_absolute);
- struct wlr_event_pointer_motion_absolute* event
- = reinterpret_cast<struct wlr_event_pointer_motion_absolute*>(data);
-
- wlr_cursor_warp_absolute(mouse->mp_cursor, event->device, event->x, event->y);
- process_cursor_motion(mouse, event->time_msec);
-}
-
-void
-Mouse::handle_cursor_button(struct wl_listener* listener, void* data)
-{
- TRACE();
-
- Mouse_ptr mouse = wl_container_of(listener, mouse, ml_cursor_button);
- struct wlr_event_pointer_button* event
- = reinterpret_cast<struct wlr_event_pointer_button*>(data);
-
- wlr_seat_pointer_notify_button(
- mouse->mp_seat->mp_wlr_seat,
- event->time_msec,
- event->button,
- event->state
- );
-
- double sx, sy;
- struct wlr_surface* surface = nullptr;
-
- View_ptr view = view_at(
- mouse->mp_server,
- mouse->mp_cursor->x,
- mouse->mp_cursor->y,
- &surface,
- &sx, &sy
- );
-
- if (event->state == WLR_BUTTON_RELEASED)
- mouse->m_cursor_mode = CursorMode::Passthrough;
- else if (false /* TODO: !focus_follows_mouse */)
- mouse->mp_seat->mp_model->focus_view(view);
-}
-
-void
-Mouse::handle_cursor_axis(struct wl_listener*, void*)
-{
- TRACE();
-
-}
-
-void
-Mouse::handle_cursor_frame(struct wl_listener* listener, void*)
-{
- TRACE();
-
- Mouse_ptr mouse = wl_container_of(listener, mouse, ml_cursor_frame);
- wlr_seat_pointer_notify_frame(mouse->mp_seat->mp_wlr_seat);
-}
-
-void
-Mouse::handle_request_start_drag(struct wl_listener*, void*)
-{
- TRACE();
-
-}
-
-void
-Mouse::handle_start_drag(struct wl_listener*, void*)
-{
- TRACE();
-
-}
-
-void
-Mouse::handle_request_set_cursor(struct wl_listener*, void*)
-{
- TRACE();
-
-}
diff --git a/src/kranewl/input/seat.cc b/src/kranewl/input/seat.cc
@@ -1,7 +1,7 @@
#include <trace.hh>
#include <kranewl/input/keyboard.hh>
-#include <kranewl/input/mouse.hh>
+#include <kranewl/input/cursor.hh>
#include <kranewl/input/seat.hh>
#include <kranewl/util.hh>
@@ -35,7 +35,7 @@ Seat::Seat(
mp_idle_inhibit_manager(idle_inhibit_manager),
mp_virtual_keyboard_manager(virtual_keyboard_manager),
mp_keyboard_shortcuts_inhibit_manager(keyboard_shortcuts_inhibit_manager),
- mp_mouse(new Mouse(
+ mp_cursor(new Cursor(
server,
this,
cursor,
@@ -65,7 +65,7 @@ Seat::~Seat()
{
TRACE();
- delete mp_mouse;
+ delete mp_cursor;
for (Keyboard_ptr keyboard : m_keyboards)
delete keyboard;
diff --git a/src/kranewl/layout.cc b/src/kranewl/layout.cc
@@ -1536,7 +1536,7 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
}
default:
{
- spdlog::critical("no associated configuration defined");
+ spdlog::critical("No associated configuration defined");
std::exit(EXIT_FAILURE);
}
}
@@ -1583,7 +1583,7 @@ LayoutHandler::Layout::kind_to_default_data(LayoutKind kind)
}
default:
{
- spdlog::critical("no associated default data defined");
+ spdlog::critical("No associated default data defined");
std::exit(EXIT_FAILURE);
}
}
diff --git a/src/kranewl/model.cc b/src/kranewl/model.cc
@@ -7,8 +7,9 @@
#include <kranewl/context.hh>
#include <kranewl/cycle.t.hh>
#include <kranewl/exec.hh>
-#include <kranewl/input/mouse.hh>
-#include <kranewl/input/keybindings.hh>
+#include <kranewl/input/cursor-bindings.hh>
+#include <kranewl/input/cursor.hh>
+#include <kranewl/input/key-bindings.hh>
#include <kranewl/server.hh>
#include <kranewl/tree/output.hh>
#include <kranewl/tree/view.hh>
@@ -56,7 +57,7 @@ Model::Model(
m_unmanaged_views{},
mp_focus(nullptr),
m_key_bindings(Bindings::key_bindings),
- m_mouse_bindings{}
+ m_cursor_bindings(Bindings::cursor_bindings)
{
TRACE();
@@ -119,7 +120,7 @@ Model::exit()
mp_server->terminate();
}
-const View_ptr
+View_ptr
Model::focused_view() const
{
return mp_focus;
@@ -131,6 +132,12 @@ Model::key_bindings() const
return m_key_bindings;
}
+CursorBindings const&
+Model::cursor_bindings() const
+{
+ return m_cursor_bindings;
+}
+
Output_ptr
Model::create_output(
struct wlr_output* wlr_output,
@@ -244,13 +251,6 @@ Model::focus_view(View_ptr view)
}
void
-Model::unfocus_view(View_ptr view)
-{
- TRACE();
-
-}
-
-void
Model::place_view(Placement& placement)
{
TRACE();
diff --git a/src/kranewl/server.cc b/src/kranewl/server.cc
@@ -5,7 +5,6 @@
#include <kranewl/exec.hh>
#include <kranewl/input/keyboard.hh>
#include <kranewl/model.hh>
-#include <kranewl/tree/client.hh>
#include <kranewl/tree/output.hh>
#include <kranewl/tree/view.hh>
#include <kranewl/tree/xdg_view.hh>
@@ -61,7 +60,9 @@ extern "C" {
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/util/box.h>
#ifdef XWAYLAND
+#define Cursor Cursor_
#include <X11/Xlib.h>
+#undef Cursor
#include <wlr/xwayland.h>
#endif
}
@@ -454,7 +455,7 @@ Server::handle_new_input(struct wl_listener* listener, void* data)
case WLR_INPUT_DEVICE_POINTER:
{
wlr_cursor_attach_input_device(
- server->m_seat.mp_mouse->mp_cursor,
+ server->m_seat.mp_cursor->mp_wlr_cursor,
device
);
break;
@@ -518,13 +519,6 @@ Server::handle_xdg_toplevel_request_resize(struct wl_listener*, void*)
}
-void
-Server::handle_xdg_toplevel_handle_moveresize(View_ptr, CursorMode, uint32_t)
-{
- TRACE();
-
-}
-
#ifdef XWAYLAND
void
Server::handle_xwayland_ready(struct wl_listener*, void*)
diff --git a/src/kranewl/tree/client.cc b/src/kranewl/tree/client.cc
@@ -1,210 +0,0 @@
-#include <kranewl/tree/client.hh>
-
-// https://github.com/swaywm/wlroots/issues/682
-#include <pthread.h>
-#define class class_
-#define namespace namespace_
-#define static
-extern "C" {
-#include <wlr/types/wlr_xdg_shell.h>
-#ifdef XWAYLAND
-#include <wlr/xwayland.h>
-#endif
-}
-#undef static
-#undef class
-#undef namespace
-
-Client::Client(
- Server_ptr server,
- Surface surface,
- Output_ptr output,
- Context_ptr context,
- Workspace_ptr workspace
-)
- : m_uid{surface.uid()},
- mp_server{server},
- m_surface{surface},
- mp_output{output},
- mp_context{context},
- mp_workspace{workspace},
- m_free_region({}),
- m_tile_region({}),
- m_active_region({}),
- m_previous_region({}),
- m_inner_region({}),
- m_tile_decoration({}, DEFAULT_COLOR_SCHEME),
- m_free_decoration({}, DEFAULT_COLOR_SCHEME),
- m_active_decoration({}, DEFAULT_COLOR_SCHEME),
- m_focused(false),
- m_mapped(false),
- m_managed(true),
- m_urgent(false),
- m_floating(false),
- m_fullscreen(false),
- m_contained(false),
- m_invincible(false),
- m_sticky(false),
- m_iconifyable(true),
- m_iconified(false),
- m_disowned(false),
- m_producing(true),
- m_attaching(false),
- m_last_focused(std::chrono::steady_clock::now()),
- m_last_touched(std::chrono::steady_clock::now()),
- m_managed_since(std::chrono::steady_clock::now()),
- m_outside_state{OutsideState::Unfocused}
-{}
-
-Client::~Client()
-{}
-
-Client::OutsideState
-Client::get_outside_state() const noexcept
-{
- if (m_urgent)
- return Client::OutsideState::Urgent;
-
- return m_outside_state;
-}
-
-struct wlr_surface*
-Client::get_surface() noexcept
-{
- switch (m_surface.type) {
- case SurfaceType::XDGShell: //fallthrough
- case SurfaceType::LayerShell: return m_surface.xdg->surface;
- case SurfaceType::X11Managed: //fallthrough
- case SurfaceType::X11Unmanaged: return m_surface.xwayland->surface;
- }
-
- return nullptr;
-}
-
-void
-Client::focus() noexcept
-{
- m_focused = true;
- m_last_focused = std::chrono::steady_clock::now();
-
- switch (m_outside_state) {
- case OutsideState::Unfocused: m_outside_state = OutsideState::Focused; return;
- case OutsideState::UnfocusedDisowned: m_outside_state = OutsideState::FocusedDisowned; return;
- case OutsideState::UnfocusedSticky: m_outside_state = OutsideState::FocusedSticky; return;
- default: return;
- }
-}
-
-void
-Client::unfocus() noexcept
-{
- m_focused = false;
-
- switch (m_outside_state) {
- case OutsideState::Focused: m_outside_state = OutsideState::Unfocused; return;
- case OutsideState::FocusedDisowned: m_outside_state = OutsideState::UnfocusedDisowned; return;
- case OutsideState::FocusedSticky: m_outside_state = OutsideState::UnfocusedSticky; return;
- default: return;
- }
-}
-
-void
-Client::stick() noexcept
-{
- m_sticky = true;
-
- switch (m_outside_state) {
- case OutsideState::Focused: m_outside_state = OutsideState::FocusedSticky; return;
- case OutsideState::Unfocused: m_outside_state = OutsideState::UnfocusedSticky; return;
- default: return;
- }
-}
-
-void
-Client::unstick() noexcept
-{
- m_sticky = false;
-
- switch (m_outside_state) {
- case OutsideState::FocusedSticky: m_outside_state = OutsideState::Focused; return;
- case OutsideState::UnfocusedSticky: m_outside_state = OutsideState::Unfocused; return;
- default: return;
- }
-}
-
-void
-Client::disown() noexcept
-{
- m_disowned = true;
-
- switch (m_outside_state) {
- case OutsideState::Focused: m_outside_state = OutsideState::FocusedDisowned; return;
- case OutsideState::Unfocused: m_outside_state = OutsideState::UnfocusedDisowned; return;
- default: return;
- }
-}
-
-void
-Client::reclaim() noexcept
-{
- m_disowned = false;
-
- switch (m_outside_state) {
- case OutsideState::FocusedDisowned: m_outside_state = OutsideState::Focused; return;
- case OutsideState::UnfocusedDisowned: m_outside_state = OutsideState::Unfocused; return;
- default: return;
- }
-}
-
-void
-Client::set_tile_region(Region& region) noexcept
-{
- m_tile_region = region;
- set_active_region(region);
-}
-
-void
-Client::set_free_region(Region& region) noexcept
-{
- m_free_region = region;
- set_active_region(region);
-}
-
-void
-Client::set_active_region(Region& region) noexcept
-{
- m_previous_region = m_active_region;
- set_inner_region(region);
- m_active_region = region;
-}
-
-void
-Client::set_tile_decoration(Decoration const& decoration) noexcept
-{
- m_tile_decoration = decoration;
- m_active_decoration = decoration;
-}
-
-void
-Client::set_free_decoration(Decoration const& decoration) noexcept
-{
- m_free_decoration = decoration;
- m_active_decoration = decoration;
-}
-
-void
-Client::set_inner_region(Region& region) noexcept
-{
- if (m_active_decoration.frame) {
- Frame const& frame = *m_active_decoration.frame;
-
- m_inner_region.pos.x = frame.extents.left;
- m_inner_region.pos.y = frame.extents.top;
- m_inner_region.dim.w = region.dim.w - frame.extents.left - frame.extents.right;
- m_inner_region.dim.h = region.dim.h - frame.extents.top - frame.extents.bottom;
- } else {
- m_inner_region.pos.x = 0;
- m_inner_region.pos.y = 0;
- m_inner_region.dim = region.dim;
- }
-}
diff --git a/src/kranewl/tree/output.cc b/src/kranewl/tree/output.cc
@@ -118,7 +118,7 @@ Output::set_context(Context_ptr context)
TRACE();
if (!context)
- spdlog::error("output must contain a valid context");
+ spdlog::error("Output must contain a valid context");
if (mp_context)
mp_context->set_output(nullptr);
diff --git a/src/kranewl/tree/view.cc b/src/kranewl/tree/view.cc
@@ -1,6 +1,6 @@
#include <trace.hh>
-#include <kranewl/layers.hh>
+#include <kranewl/layer.hh>
#include <kranewl/server.hh>
#include <kranewl/model.hh>
#include <kranewl/tree/view.hh>
@@ -324,7 +324,7 @@ View::tile(Toggle toggle)
}
void
-View::relayer(Layer::type layer)
+View::relayer(Layer layer)
{
if (layer == m_layer)
return;
@@ -458,6 +458,13 @@ View::set_free_region(Region const& region)
}
void
+View::set_free_pos(Pos const& pos)
+{
+ m_free_region.pos = pos;
+ set_active_pos(pos);
+}
+
+void
View::set_tile_region(Region const& region)
{
m_tile_region = region;
@@ -496,6 +503,13 @@ View::set_active_region(Region const& region)
}
void
+View::set_active_pos(Pos const& pos)
+{
+ m_previous_region = m_active_region;
+ m_active_region.pos = pos;
+}
+
+void
View::set_inner_region(Region const& region)
{
if (m_active_decoration.frame) {
diff --git a/src/kranewl/tree/xdg_view.cc b/src/kranewl/tree/xdg_view.cc
@@ -1,7 +1,7 @@
#include <trace.hh>
#include <kranewl/context.hh>
-#include <kranewl/layers.hh>
+#include <kranewl/layer.hh>
#include <kranewl/model.hh>
#include <kranewl/server.hh>
#include <kranewl/tree/output.hh>