commit 7f4990d42d43000be4cfc478d01b1974055dced3
parent 8752e09d79575a20a1a6c413fff9f6e77f7109cf
Author: deurzen <max@deurzen.net>
Date: Fri, 27 May 2022 05:47:38 +0200
implements initial layout application routines
Diffstat:
26 files changed, 841 insertions(+), 257 deletions(-)
diff --git a/include/kranewl/bindings.hh b/include/kranewl/bindings.hh
@@ -1,27 +0,0 @@
-#pragma once
-
-#include <kranewl/input/keyboard.hh>
-#include <kranewl/input/mouse.hh>
-
-#include <functional>
-#include <optional>
-#include <cstdint>
-
-class Model;
-typedef class Client* Client_ptr;
-
-typedef
- std::function<void(Model&)>
- KeyboardAction;
-
-typedef
- std::function<bool(Model&, Client_ptr)>
- MouseAction;
-
-typedef
- std::unordered_map<KeyboardInput, KeyboardAction>
- KeyBindings;
-
-typedef
- std::unordered_map<MouseInput, MouseAction>
- MouseBindings;
diff --git a/include/kranewl/conf/config.hh b/include/kranewl/conf/config.hh
@@ -1,6 +1,6 @@
#pragma once
-#include <kranewl/bindings.hh>
+#include <kranewl/input/bindings.hh>
#include <string>
#include <memory>
diff --git a/include/kranewl/decoration.hh b/include/kranewl/decoration.hh
@@ -8,17 +8,17 @@ struct RGBA final {
RGBA(unsigned hex_)
: hex(hex_)
{
- values[0] = static_cast<float>(hex & 0xff) / 255.f;
- values[1] = static_cast<float>((hex >> 8) & 0xff) / 255.f;
- values[2] = static_cast<float>((hex >> 16) & 0xff) / 255.f;
- values[3] = static_cast<float>((hex >> 24) & 0xff) / 255.f;
+ values[3] = static_cast<float>(hex & 0xff) / 255.f;
+ values[2] = static_cast<float>((hex >> 8) & 0xff) / 255.f;
+ values[1] = static_cast<float>((hex >> 16) & 0xff) / 255.f;
+ values[0] = static_cast<float>((hex >> 24) & 0xff) / 255.f;
}
RGBA(const float values_[4])
- : hex(((static_cast<unsigned>(values_[3] * 255.f) & 0xff) << 24) +
- ((static_cast<unsigned>(values_[2] * 255.f) & 0xff) << 16) +
- ((static_cast<unsigned>(values_[1] * 255.f) & 0xff) << 8) +
- ((static_cast<unsigned>(values_[0] * 255.f) & 0xff)))
+ : hex(((static_cast<unsigned>(values_[0] * 255.f) & 0xff) << 24) +
+ ((static_cast<unsigned>(values_[1] * 255.f) & 0xff) << 16) +
+ ((static_cast<unsigned>(values_[2] * 255.f) & 0xff) << 8) +
+ ((static_cast<unsigned>(values_[3] * 255.f) & 0xff)))
{
values[0] = values_[0];
values[1] = values_[1];
@@ -41,22 +41,22 @@ struct ColorScheme final {
};
const static ColorScheme DEFAULT_COLOR_SCHEME = ColorScheme{
- .focused = {0x8181A6FF},
- .fdisowned = {0xc1c1c1FF},
- .fsticky = {0x5F8787FF},
- .unfocused = {0x333333FF},
- .udisowned = {0x999999FF},
- .usticky = {0x444444FF},
- .urgent = {0x87875FFF},
+ .focused = RGBA{0x8181A6FF},
+ .fdisowned = RGBA{0xc1c1c1FF},
+ .fsticky = RGBA{0x5F8787FF},
+ .unfocused = RGBA{0x333333FF},
+ .udisowned = RGBA{0x999999FF},
+ .usticky = RGBA{0x444444FF},
+ .urgent = RGBA{0x87875FFF},
};
struct Frame final {
Extents extents;
- ColorScheme colorscheme;
};
struct Decoration final {
std::optional<Frame> frame;
+ ColorScheme colorscheme;
Extents const& extents() const
{
@@ -70,11 +70,12 @@ struct Decoration final {
const Decoration NO_DECORATION = Decoration{
std::nullopt,
+ DEFAULT_COLOR_SCHEME
};
const Decoration FREE_DECORATION = Decoration{
Frame{
- Extents{3, 1, 1, 1},
- DEFAULT_COLOR_SCHEME
- }
+ Extents{3, 1, 1, 1}
+ },
+ DEFAULT_COLOR_SCHEME
};
diff --git a/include/kranewl/input/bindings.hh b/include/kranewl/input/bindings.hh
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <kranewl/input/keyboard.hh>
+#include <kranewl/input/mouse.hh>
+
+#include <cstdint>
+#include <functional>
+#include <optional>
+
+class Model;
+typedef struct View* View_ptr;
+
+typedef
+ std::function<void(Model&)>
+ KeyboardAction;
+
+typedef
+ std::function<bool(Model&, View_ptr)>
+ MouseAction;
+
+typedef
+ std::unordered_map<KeyboardInput, KeyboardAction>
+ KeyBindings;
+
+typedef
+ std::unordered_map<MouseInput, MouseAction>
+ MouseBindings;
diff --git a/include/kranewl/input/keybindings.hh b/include/kranewl/input/keybindings.hh
@@ -0,0 +1,109 @@
+#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())
+},
+{ { 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)
+},
+};
+
+}
+#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/keyboard.hh b/include/kranewl/input/keyboard.hh
@@ -8,6 +8,11 @@ extern "C" {
#include <cstdint>
#include <unordered_set>
+struct KeyboardInput {
+ xkb_keysym_t keysym;
+ uint32_t modifiers;
+};
+
typedef class Server* Server_ptr;
typedef class Seat* Seat_ptr;
@@ -30,10 +35,12 @@ typedef struct Keyboard {
}* Keyboard_ptr;
-struct KeyboardInput {
- uint32_t mod;
- xkb_keysym_t keysym;
-};
+inline bool
+operator==(KeyboardInput const& lhs, KeyboardInput const& rhs)
+{
+ return lhs.keysym == rhs.keysym
+ && lhs.modifiers == rhs.modifiers;
+}
namespace std
{
@@ -42,10 +49,10 @@ namespace std
std::size_t
operator()(KeyboardInput const& input) const
{
- std::size_t mod_hash = std::hash<uint32_t>()(input.mod);
std::size_t key_hash = std::hash<xkb_keysym_t>()(input.keysym);
+ std::size_t modifiers_hash = std::hash<uint32_t>()(input.modifiers);
- return mod_hash ^ key_hash;
+ return modifiers_hash ^ key_hash;
}
};
}
diff --git a/include/kranewl/input/mousebindings.hh b/include/kranewl/input/mousebindings.hh
@@ -0,0 +1,3 @@
+#pragma once
+
+
diff --git a/include/kranewl/input/seat.hh b/include/kranewl/input/seat.hh
@@ -29,7 +29,20 @@ public:
Middle = 274,
};
- Seat(Server_ptr, Model_ptr, struct wlr_seat*, struct wlr_cursor*);
+ Seat(
+ Server_ptr,
+ Model_ptr,
+ struct wlr_seat*,
+ struct wlr_idle*,
+ struct wlr_cursor*,
+ struct wlr_input_inhibit_manager*,
+ struct wlr_idle_inhibit_manager_v1*,
+ struct wlr_pointer_constraints_v1*,
+ struct wlr_relative_pointer_manager_v1*,
+ struct wlr_virtual_pointer_manager_v1*,
+ struct wlr_virtual_keyboard_manager_v1*,
+ struct wlr_keyboard_shortcuts_inhibit_manager_v1*
+ );
~Seat();
Keyboard_ptr create_keyboard(struct wlr_input_device*);
@@ -47,14 +60,25 @@ public:
static void handle_request_set_cursor(struct wl_listener*, void*);
static void handle_request_set_selection(struct wl_listener*, void*);
static void handle_request_set_primary_selection(struct wl_listener*, void*);
+ static void handle_inhibit_manager_new_inhibitor(struct wl_listener*, void*);
+ static void handle_inhibit_manager_inhibit_activate(struct wl_listener*, void*);
+ static void handle_inhibit_manager_inhibit_deactivate(struct wl_listener*, void*);
public:
Server_ptr mp_server;
Model_ptr mp_model;
- struct wlr_seat* mp_seat;
+ struct wlr_seat* mp_wlr_seat;
+ struct wlr_idle* mp_idle;
struct wlr_cursor* mp_cursor;
struct wlr_xcursor_manager* mp_cursor_manager;
+ struct wlr_input_inhibit_manager* mp_input_inhibit_manager;
+ struct wlr_idle_inhibit_manager_v1* mp_idle_inhibit_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 wlr_virtual_keyboard_manager_v1* mp_virtual_keyboard_manager;
+ struct wlr_keyboard_shortcuts_inhibit_manager_v1* mp_keyboard_shortcuts_inhibit_manager;
CursorMode m_cursor_mode;
std::vector<Keyboard_ptr> m_keyboards;
@@ -79,5 +103,8 @@ public:
struct wl_listener ml_request_set_cursor;
struct wl_listener ml_request_set_selection;
struct wl_listener ml_request_set_primary_selection;
+ struct wl_listener ml_inhibit_manager_new_inhibitor;
+ struct wl_listener ml_inhibit_manager_inhibit_activate;
+ struct wl_listener ml_inhibit_manager_inhibit_deactivate;
}* Seat_ptr;
diff --git a/include/kranewl/model.hh b/include/kranewl/model.hh
@@ -1,9 +1,10 @@
#pragma once
-#include <kranewl/bindings.hh>
#include <kranewl/common.hh>
#include <kranewl/cycle.hh>
#include <kranewl/geometry.hh>
+#include <kranewl/input/bindings.hh>
+#include <kranewl/layout.hh>
#include <kranewl/placement.hh>
#include <kranewl/tree/view.hh>
@@ -36,6 +37,8 @@ public:
void register_server(Server_ptr);
void exit();
+ KeyBindings const& key_bindings() const;
+
Output_ptr create_output(struct wlr_output*, struct wlr_scene_output*, Region const&&);
void register_output(Output_ptr);
void unregister_output(Output_ptr);
@@ -54,20 +57,35 @@ 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();
+
void move_view_to_workspace(View_ptr, Index);
void move_view_to_workspace(View_ptr, Workspace_ptr);
void move_view_to_context(View_ptr, Index);
void move_view_to_context(View_ptr, Context_ptr);
void move_view_to_output(View_ptr, Index);
void move_view_to_output(View_ptr, Output_ptr);
-
void move_view_to_focused_output(View_ptr);
+ void activate_workspace(Index);
+ void activate_workspace(Workspace_ptr);
+ void activate_context(Index);
+ void activate_context(Context_ptr);
+ void activate_output(Index);
+ void activate_output(Output_ptr);
+
+ void toggle_layout();
+ void set_layout(LayoutHandler::LayoutKind);
+ void set_layout_retain_region(LayoutHandler::LayoutKind);
+
void apply_layout(Index);
void apply_layout(Workspace_ptr);
+ bool is_free(View_ptr) const;
+
void spawn_external(std::string&&) const;
private:
@@ -98,7 +116,7 @@ private:
View_ptr mp_focus;
- KeyBindings m_key_bindings;
- MouseBindings m_mouse_bindings;
+ const KeyBindings m_key_bindings;
+ const MouseBindings m_mouse_bindings;
};
diff --git a/include/kranewl/server.hh b/include/kranewl/server.hh
@@ -13,8 +13,8 @@ extern "C" {
#include <string>
typedef class Model* Model_ptr;
-typedef class View* View_ptr;
typedef class Server* Server_ptr;
+typedef struct View* View_ptr;
typedef class Server final {
enum class CursorMode {
@@ -28,8 +28,9 @@ public:
~Server();
void run() noexcept;
+ void terminate() noexcept;
- void moveresize_view(View_ptr, Region const&, Extents const&, bool);
+ void relinquish_focus();
private:
static void handle_new_output(struct wl_listener*, void*);
@@ -40,10 +41,6 @@ private:
static void handle_new_layer_shell_surface(struct wl_listener*, void*);
static void handle_xdg_activation(struct wl_listener*, void*);
static void handle_new_input(struct wl_listener*, void*);
- static void handle_inhibit_activate(struct wl_listener*, void*);
- static void handle_inhibit_deactivate(struct wl_listener*, void*);
- static void handle_idle_inhibitor_create(struct wl_listener*, void*);
- static void handle_idle_inhibitor_destroy(struct wl_listener*, void*);
static void handle_xdg_new_toplevel_decoration(struct wl_listener*, void*);
static void handle_xdg_toplevel_map(struct wl_listener*, void*);
static void handle_xdg_toplevel_unmap(struct wl_listener*, void*);
@@ -86,16 +83,8 @@ private:
struct wlr_xdg_activation_v1* mp_xdg_activation;
struct wlr_output_manager_v1* mp_output_manager;
struct wlr_presentation* mp_presentation;
- 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_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 wlr_virtual_keyboard_manager_v1* mp_virtual_keyboard_manager;
- struct wlr_input_inhibit_manager* mp_input_inhibit_manager;
- struct wlr_idle_inhibit_manager_v1* mp_idle_inhibit_manager;
- struct wlr_keyboard_shortcuts_inhibit_manager_v1* mp_keyboard_shortcuts_inhibit_manager;
struct wl_listener ml_new_output;
struct wl_listener ml_output_layout_change;
@@ -105,10 +94,6 @@ private:
struct wl_listener ml_new_layer_shell_surface;
struct wl_listener ml_xdg_activation;
struct wl_listener ml_new_input;
- struct wl_listener ml_inhibit_activate;
- struct wl_listener ml_inhibit_deactivate;
- struct wl_listener ml_idle_inhibitor_create;
- struct wl_listener ml_idle_inhibitor_destroy;
struct wl_listener ml_xdg_new_toplevel_decoration;
#ifdef XWAYLAND
struct wl_listener ml_xwayland_ready;
diff --git a/include/kranewl/tree/view.hh b/include/kranewl/tree/view.hh
@@ -68,8 +68,11 @@ typedef struct View {
virtual ~View();
- static void map_view(View_ptr, struct wlr_surface*, bool, struct wlr_output*, bool);
- static void unmap_view(View_ptr);
+ void map(struct wlr_surface*, bool, struct wlr_output*, bool);
+ void unmap();
+
+ virtual void focus(bool) = 0;
+ virtual void moveresize(Region const&, Extents const&, bool) = 0;
static bool
is_free(View_ptr view)
diff --git a/include/kranewl/tree/xdg_view.hh b/include/kranewl/tree/xdg_view.hh
@@ -22,6 +22,9 @@ typedef struct XDGView final : public View {
~XDGView();
+ void focus(bool) override;
+ void moveresize(Region const&, Extents const&, bool) override;
+
static void handle_foreign_activate_request(struct wl_listener*, void*);
static void handle_foreign_fullscreen_request(struct wl_listener*, void*);
static void handle_foreign_close_request(struct wl_listener*, void*);
diff --git a/include/kranewl/tree/xwayland_view.hh b/include/kranewl/tree/xwayland_view.hh
@@ -21,6 +21,9 @@ typedef struct XWaylandView final : public View {
~XWaylandView();
+ void focus(bool) override;
+ void moveresize(Region const&, Extents const&, bool) override;
+
static void handle_foreign_activate_request(struct wl_listener*, void*);
static void handle_foreign_fullscreen_request(struct wl_listener*, void*);
static void handle_foreign_close_request(struct wl_listener*, void*);
diff --git a/include/kranewl/util.hh b/include/kranewl/util.hh
@@ -96,13 +96,6 @@ namespace Util
}
template <typename K, typename V>
- V&
- at(std::unordered_map<K, V>& c, K& key)
- {
- return c.at(key);
- }
-
- template <typename K, typename V>
std::optional<const V>
const_retrieve(std::unordered_map<K, V> const& c, K const& key)
{
@@ -114,6 +107,13 @@ namespace Util
return iter->second;
}
+ template <typename K, typename V>
+ V&
+ at(std::unordered_map<K, V>& c, K& key)
+ {
+ return c.at(key);
+ }
+
template <typename Container>
typename std::enable_if<is_iterable<Container>::value, const std::optional<const std::size_t>>::type
index_of(Container const& c, typename Container::value_type const& t)
diff --git a/src/kranewl/exec.cc b/src/kranewl/exec.cc
@@ -8,7 +8,7 @@ void
exec_external(std::string& command) {
if (!fork()) {
setsid();
- execl("/bin/sh", "/bin/sh", "-c", ("exec " + command).c_str(), NULL);
+ execl("/bin/sh", "/bin/sh", "-c", ("exec " + command).c_str(), nullptr);
std::exit(EXIT_SUCCESS);
}
}
diff --git a/src/kranewl/input/keyboard.cc b/src/kranewl/input/keyboard.cc
@@ -1,6 +1,18 @@
#include <trace.hh>
#include <kranewl/input/keyboard.hh>
+#include <kranewl/input/seat.hh>
+#include <kranewl/model.hh>
+#include <kranewl/server.hh>
+#include <kranewl/util.hh>
+
+extern "C" {
+#include <wlr/types/wlr_idle.h>
+#include <wlr/types/wlr_input_device.h>
+#include <wlr/types/wlr_input_inhibitor.h>
+#include <wlr/types/wlr_keyboard.h>
+#include <xkbcommon/xkbcommon.h>
+}
Keyboard::Keyboard(Server_ptr server, Seat_ptr seat, struct wlr_input_device* device)
: mp_server(server),
@@ -10,6 +22,9 @@ Keyboard::Keyboard(Server_ptr server, Seat_ptr seat, struct wlr_input_device* de
ml_modifiers({ .notify = handle_modifiers }),
ml_key({ .notify = handle_key })
{
+ wl_signal_add(&mp_device->keyboard->events.modifiers, &ml_modifiers);
+ wl_signal_add(&mp_device->keyboard->events.key, &ml_key);
+ wl_signal_add(&mp_device->events.destroy, &ml_destroy);
}
Keyboard::~Keyboard()
@@ -23,15 +38,83 @@ Keyboard::handle_destroy(struct wl_listener*, void*)
}
void
-Keyboard::handle_modifiers(struct wl_listener*, void*)
+Keyboard::handle_modifiers(struct wl_listener* listener, void*)
{
TRACE();
+ Keyboard_ptr keyboard = wl_container_of(listener, keyboard, ml_modifiers);
+ Seat_ptr seat = keyboard->mp_seat;
+
+ wlr_seat_set_keyboard(seat->mp_wlr_seat, keyboard->mp_device);
+ wlr_seat_keyboard_notify_modifiers(
+ seat->mp_wlr_seat,
+ &keyboard->mp_device->keyboard->modifiers
+ );
+}
+
+static bool
+process_keybinding(Model_ptr model, KeyboardInput input)
+{
+ TRACE();
+
+ auto binding = Util::const_retrieve(model->key_bindings(), input);
+
+ if (binding) {
+ (*binding)(*model);
+ return true;
+ }
+
+ return false;
}
void
-Keyboard::handle_key(struct wl_listener*, void*)
+Keyboard::handle_key(struct wl_listener* listener, void* data)
{
TRACE();
+ Keyboard_ptr keyboard = wl_container_of(listener, keyboard, ml_key);
+ Seat_ptr seat = keyboard->mp_seat;
+
+ struct wlr_event_keyboard_key* event
+ = reinterpret_cast<struct wlr_event_keyboard_key*>(data);
+
+ uint32_t keycode = event->keycode + 8;
+ uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->mp_device->keyboard);
+
+ const xkb_keysym_t* keysyms;
+ int symcount = xkb_state_key_get_syms(
+ keyboard->mp_device->keyboard->xkb_state,
+ keycode,
+ &keysyms
+ );
+
+ wlr_idle_notify_activity(
+ seat->mp_idle,
+ seat->mp_wlr_seat
+ );
+
+ bool key_press_handled = false;
+
+ if (!seat->mp_input_inhibit_manager->active_inhibitor
+ && event->state == WL_KEYBOARD_KEY_STATE_PRESSED)
+ {
+ for (int i = 0; i < symcount; ++i)
+ key_press_handled |= process_keybinding(
+ seat->mp_model,
+ KeyboardInput{
+ keysyms[i],
+ modifiers & ~WLR_MODIFIER_CAPS
+ }
+ );
+ }
+
+ if (!key_press_handled) {
+ wlr_seat_set_keyboard(seat->mp_wlr_seat, keyboard->mp_device);
+ wlr_seat_keyboard_notify_key(
+ seat->mp_wlr_seat,
+ event->time_msec,
+ event->keycode,
+ event->state
+ );
+ }
}
diff --git a/src/kranewl/input/seat.cc b/src/kranewl/input/seat.cc
@@ -8,19 +8,37 @@ extern "C" {
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_xcursor_manager.h>
+#include <wlr/types/wlr_idle_inhibit_v1.h>
+#include <wlr/types/wlr_input_inhibitor.h>
}
Seat::Seat(
Server_ptr server,
Model_ptr model,
struct wlr_seat* seat,
- struct wlr_cursor* cursor
+ struct wlr_idle* idle,
+ struct wlr_cursor* cursor,
+ struct wlr_input_inhibit_manager* input_inhibit_manager,
+ struct wlr_idle_inhibit_manager_v1* idle_inhibit_manager,
+ 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,
+ struct wlr_virtual_keyboard_manager_v1* virtual_keyboard_manager,
+ struct wlr_keyboard_shortcuts_inhibit_manager_v1* keyboard_shortcuts_inhibit_manager
)
: mp_server(server),
mp_model(model),
- mp_seat(seat),
+ mp_wlr_seat(seat),
+ mp_idle(idle),
mp_cursor(cursor),
- mp_cursor_manager(wlr_xcursor_manager_create(NULL, 24)),
+ mp_cursor_manager(wlr_xcursor_manager_create(nullptr, 24)),
+ mp_input_inhibit_manager(input_inhibit_manager),
+ mp_idle_inhibit_manager(idle_inhibit_manager),
+ mp_pointer_constraints(pointer_constraints),
+ mp_relative_pointer_manager(relative_pointer_manager),
+ mp_virtual_pointer_manager(virtual_pointer_manager),
+ mp_virtual_keyboard_manager(virtual_keyboard_manager),
+ mp_keyboard_shortcuts_inhibit_manager(keyboard_shortcuts_inhibit_manager),
ml_destroy({ .notify = Seat::handle_destroy }),
ml_cursor_motion({ .notify = Seat::handle_cursor_motion }),
ml_cursor_motion_absolute({ .notify = Seat::handle_cursor_motion_absolute }),
@@ -31,7 +49,10 @@ Seat::Seat(
ml_start_drag({ .notify = Seat::handle_start_drag }),
ml_request_set_cursor({ .notify = Seat::handle_request_set_cursor }),
ml_request_set_selection({ .notify = Seat::handle_request_set_selection }),
- ml_request_set_primary_selection({ .notify = Seat::handle_request_set_primary_selection })
+ ml_request_set_primary_selection({ .notify = Seat::handle_request_set_primary_selection }),
+ ml_inhibit_manager_new_inhibitor({ .notify = Seat::handle_inhibit_manager_new_inhibitor }),
+ ml_inhibit_manager_inhibit_activate({ .notify = Seat::handle_inhibit_manager_inhibit_activate }),
+ ml_inhibit_manager_inhibit_deactivate({ .notify = Seat::handle_inhibit_manager_inhibit_deactivate })
{
TRACE();
@@ -48,6 +69,9 @@ Seat::Seat(
wl_signal_add(&seat->events.request_set_cursor, &ml_request_set_cursor);
wl_signal_add(&seat->events.request_set_selection, &ml_request_set_selection);
wl_signal_add(&seat->events.request_set_primary_selection, &ml_request_set_primary_selection);
+ wl_signal_add(&mp_idle_inhibit_manager->events.new_inhibitor, &ml_inhibit_manager_new_inhibitor);
+ wl_signal_add(&mp_input_inhibit_manager->events.activate, &ml_inhibit_manager_inhibit_activate);
+ wl_signal_add(&mp_input_inhibit_manager->events.deactivate, &ml_inhibit_manager_inhibit_deactivate);
}
Seat::~Seat()
@@ -79,7 +103,7 @@ process_cursor_motion(Seat_ptr seat, uint32_t time)
}
double sx, sy;
- struct wlr_surface* surface = NULL;
+ struct wlr_surface* surface = nullptr;
// TODO: get client under cursor
if (true /* no client under cursor? */) {
@@ -91,10 +115,10 @@ process_cursor_motion(Seat_ptr seat, uint32_t time)
}
if (surface) {
- wlr_seat_pointer_notify_enter(seat->mp_seat, surface, sx, sy);
- wlr_seat_pointer_notify_motion(seat->mp_seat, time, sx, sy);
+ wlr_seat_pointer_notify_enter(seat->mp_wlr_seat, surface, sx, sy);
+ wlr_seat_pointer_notify_motion(seat->mp_wlr_seat, time, sx, sy);
} else
- wlr_seat_pointer_clear_focus(seat->mp_seat);
+ wlr_seat_pointer_clear_focus(seat->mp_wlr_seat);
}
Keyboard_ptr
@@ -170,7 +194,7 @@ 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);
+ wlr_seat_pointer_notify_frame(seat->mp_wlr_seat);
}
void
@@ -207,3 +231,24 @@ Seat::handle_request_set_primary_selection(struct wl_listener*, void*)
TRACE();
}
+
+void
+Seat::handle_inhibit_manager_new_inhibitor(struct wl_listener*, void*)
+{
+ TRACE();
+
+}
+
+void
+Seat::handle_inhibit_manager_inhibit_activate(struct wl_listener*, void*)
+{
+ TRACE();
+
+}
+
+void
+Seat::handle_inhibit_manager_inhibit_deactivate(struct wl_listener*, void*)
+{
+ TRACE();
+
+}
diff --git a/src/kranewl/layout.cc b/src/kranewl/layout.cc
@@ -1353,9 +1353,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
Placement::PlacementMethod::Tile,
Decoration{
Frame{
- Extents{0, 0, 3, 0},
- DEFAULT_COLOR_SCHEME
- }
+ Extents{0, 0, 3, 0}
+ },
+ DEFAULT_COLOR_SCHEME
},
true,
true,
@@ -1370,9 +1370,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
Placement::PlacementMethod::Tile,
Decoration{
Frame{
- Extents{0, 0, 3, 0},
- DEFAULT_COLOR_SCHEME
- }
+ Extents{0, 0, 3, 0}
+ },
+ DEFAULT_COLOR_SCHEME
},
true,
true,
@@ -1387,9 +1387,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
Placement::PlacementMethod::Tile,
Decoration{
Frame{
- Extents{0, 0, 3, 0},
- DEFAULT_COLOR_SCHEME
- }
+ Extents{0, 0, 3, 0}
+ },
+ DEFAULT_COLOR_SCHEME
},
true,
true,
@@ -1404,9 +1404,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
Placement::PlacementMethod::Tile,
Decoration{
Frame{
- Extents{1, 1, 0, 0},
- DEFAULT_COLOR_SCHEME
- }
+ Extents{1, 1, 0, 0}
+ },
+ DEFAULT_COLOR_SCHEME
},
true,
true,
@@ -1421,9 +1421,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
Placement::PlacementMethod::Tile,
Decoration{
Frame{
- Extents{1, 1, 0, 0},
- DEFAULT_COLOR_SCHEME
- }
+ Extents{1, 1, 0, 0}
+ },
+ DEFAULT_COLOR_SCHEME
},
true,
false,
@@ -1438,9 +1438,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
Placement::PlacementMethod::Tile,
Decoration{
Frame{
- Extents{0, 0, 3, 0},
- DEFAULT_COLOR_SCHEME
- }
+ Extents{0, 0, 3, 0}
+ },
+ DEFAULT_COLOR_SCHEME
},
true,
true,
@@ -1455,9 +1455,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
Placement::PlacementMethod::Tile,
Decoration{
Frame{
- Extents{0, 0, 3, 0},
- DEFAULT_COLOR_SCHEME
- }
+ Extents{0, 0, 3, 0}
+ },
+ DEFAULT_COLOR_SCHEME
},
true,
false,
@@ -1472,9 +1472,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
Placement::PlacementMethod::Tile,
Decoration{
Frame{
- Extents{0, 0, 3, 0},
- DEFAULT_COLOR_SCHEME
- }
+ Extents{0, 0, 3, 0}
+ },
+ DEFAULT_COLOR_SCHEME
},
true,
true,
@@ -1489,9 +1489,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
Placement::PlacementMethod::Tile,
Decoration{
Frame{
- Extents{0, 0, 3, 0},
- DEFAULT_COLOR_SCHEME
- }
+ Extents{0, 0, 3, 0}
+ },
+ DEFAULT_COLOR_SCHEME
},
true,
false,
@@ -1506,9 +1506,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
Placement::PlacementMethod::Tile,
Decoration{
Frame{
- Extents{3, 0, 0, 0},
- DEFAULT_COLOR_SCHEME
- }
+ Extents{3, 0, 0, 0}
+ },
+ DEFAULT_COLOR_SCHEME
},
true,
true,
@@ -1523,9 +1523,9 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
Placement::PlacementMethod::Tile,
Decoration{
Frame{
- Extents{3, 0, 0, 0},
- DEFAULT_COLOR_SCHEME
- }
+ Extents{3, 0, 0, 0}
+ },
+ DEFAULT_COLOR_SCHEME
},
true,
false,
diff --git a/src/kranewl/main.cc b/src/kranewl/main.cc
@@ -19,7 +19,7 @@ int
main(int argc, char** argv)
{
#ifndef NDEBUG
- /* wlr_log_init(WLR_DEBUG, NULL); */
+ /* wlr_log_init(WLR_DEBUG, nullptr); */
#ifdef TRACING_ENABLED
spdlog::set_level(spdlog::level::trace);
#else
diff --git a/src/kranewl/model.cc b/src/kranewl/model.cc
@@ -8,6 +8,7 @@
#include <kranewl/cycle.t.hh>
#include <kranewl/exec.hh>
#include <kranewl/input/mouse.hh>
+#include <kranewl/input/keybindings.hh>
#include <kranewl/server.hh>
#include <kranewl/tree/output.hh>
#include <kranewl/tree/view.hh>
@@ -54,7 +55,7 @@ Model::Model(
m_sticky_views{},
m_unmanaged_views{},
mp_focus(nullptr),
- m_key_bindings{},
+ m_key_bindings(Bindings::key_bindings),
m_mouse_bindings{}
{
TRACE();
@@ -109,6 +110,21 @@ Model::register_server(Server_ptr server)
mp_server = server;
}
+void
+Model::exit()
+{
+ TRACE();
+
+ m_running = false;
+ mp_server->terminate();
+}
+
+KeyBindings const&
+Model::key_bindings() const
+{
+ return m_key_bindings;
+}
+
Output_ptr
Model::create_output(
struct wlr_output* wlr_output,
@@ -208,9 +224,35 @@ Model::reclaim_view(View_ptr)
}
void
-Model::focus_view(View_ptr)
+Model::focus_view(View_ptr view)
{
TRACE();
+
+ Output_ptr output = view->mp_context->output();
+
+ if (!output)
+ return;
+
+ if (!view->m_sticky) {
+ activate_workspace(view->mp_workspace);
+ mp_workspace->activate_view(view);
+ }
+
+ if (mp_focus && mp_focus != view)
+ unfocus_view(mp_focus);
+
+ view->m_urgent = false;
+ mp_focus = view;
+
+ if (mp_workspace->layout_is_persistent() || mp_workspace->layout_is_single())
+ apply_layout(mp_workspace);
+}
+
+void
+Model::unfocus_view(View_ptr view)
+{
+ TRACE();
+
}
void
@@ -258,8 +300,7 @@ Model::place_view(Placement& placement)
spdlog::info("Placing view {} at {}", view->m_uid, std::to_string(view->m_active_region));
map_view(view);
- mp_server->moveresize_view(
- view,
+ view->moveresize(
view->m_active_region,
view->m_active_decoration.extents(),
false
@@ -267,6 +308,19 @@ Model::place_view(Placement& placement)
}
void
+Model::sync_focus()
+{
+ View_ptr active = mp_workspace->active();
+
+ if (active && active != mp_focus)
+ active->focus(true);
+ else if (mp_workspace->empty()) {
+ mp_server->relinquish_focus();
+ mp_focus = nullptr;
+ }
+}
+
+void
Model::move_view_to_workspace(View_ptr view, Index index)
{
TRACE();
@@ -307,6 +361,8 @@ Model::move_view_to_workspace(View_ptr view, Workspace_ptr workspace_to)
unmap_view(view);
else
map_view(view);
+
+ sync_focus();
}
void
@@ -349,6 +405,8 @@ Model::move_view_to_context(View_ptr view, Context_ptr context_to)
unmap_view(view);
else
map_view(view);
+
+ sync_focus();
}
void
@@ -397,6 +455,8 @@ Model::move_view_to_output(View_ptr view, Output_ptr output_to)
map_view(view);
} else
unmap_view(view);
+
+ sync_focus();
}
void
@@ -407,6 +467,99 @@ Model::move_view_to_focused_output(View_ptr view)
}
void
+Model::activate_workspace(Index)
+{
+ TRACE();
+
+}
+
+void
+Model::activate_workspace(Workspace_ptr)
+{
+ TRACE();
+
+}
+
+void
+Model::activate_context(Index)
+{
+ TRACE();
+
+}
+
+void
+Model::activate_context(Context_ptr)
+{
+ TRACE();
+
+}
+
+void
+Model::activate_output(Index)
+{
+ TRACE();
+
+}
+
+void
+Model::activate_output(Output_ptr)
+{
+ TRACE();
+
+}
+
+void
+Model::toggle_layout()
+{
+ TRACE();
+
+ mp_workspace->toggle_layout();
+ apply_layout(mp_workspace);
+}
+
+void
+Model::set_layout(LayoutHandler::LayoutKind layout)
+{
+ TRACE();
+
+ mp_workspace->set_layout(layout);
+ apply_layout(mp_workspace);
+}
+
+void
+Model::set_layout_retain_region(LayoutHandler::LayoutKind layout)
+{
+ Cycle<View_ptr> const& views = mp_workspace->views();
+ std::vector<Region> regions;
+
+ bool was_tiled = !mp_workspace->layout_is_free();
+
+ if (was_tiled) {
+ regions.reserve(views.size());
+
+ std::transform(
+ views.begin(),
+ views.end(),
+ std::back_inserter(regions),
+ [=,this](View_ptr view) -> Region {
+ if (is_free(view))
+ return view->m_free_region;
+ else
+ return view->m_tile_region;
+ }
+ );
+ }
+
+ mp_workspace->set_layout(layout);
+
+ if (was_tiled && mp_workspace->layout_is_free())
+ for (std::size_t i = 0; i < views.size(); ++i)
+ views[i]->set_free_region(regions[i]);
+
+ apply_layout(mp_workspace);
+}
+
+void
Model::apply_layout(Index index)
{
TRACE();
@@ -490,8 +643,32 @@ Model::unregister_view(View_ptr view)
std::stringstream uid_stream;
uid_stream << std::hex << view->m_uid;
+ if (view->mp_workspace)
+ view->mp_workspace->remove_view(view);
+
m_view_map.erase(view->m_uid);
delete view;
spdlog::info("Unegistered view 0x{}", uid_stream.str());
+ sync_focus();
+}
+
+bool
+Model::is_free(View_ptr view) const
+{
+ return View::is_free(view)
+ || ((!view->m_fullscreen || view->m_contained)
+ && (view->m_sticky
+ ? mp_workspace
+ : view->mp_workspace
+ )->layout_is_free());
+}
+
+void
+Model::spawn_external(std::string&& command) const
+{
+ TRACE();
+
+ spdlog::info("Calling external command: {}", command);
+ exec_external(command);
}
diff --git a/src/kranewl/server.cc b/src/kranewl/server.cc
@@ -114,7 +114,20 @@ Server::Server(Model_ptr model)
m_seat([this]() {
struct wlr_cursor* cursor = wlr_cursor_create();
wlr_cursor_attach_output_layout(cursor, mp_output_layout);
- return Seat{this, mp_model, wlr_seat_create(mp_display, "seat0"), cursor};
+ return Seat{
+ this,
+ mp_model,
+ wlr_seat_create(mp_display, "seat0"),
+ wlr_idle_create(mp_display),
+ cursor,
+ wlr_input_inhibit_manager_create(mp_display),
+ wlr_idle_inhibit_v1_create(mp_display),
+ wlr_pointer_constraints_v1_create(mp_display),
+ wlr_relative_pointer_manager_v1_create(mp_display),
+ wlr_virtual_pointer_manager_v1_create(mp_display),
+ wlr_virtual_keyboard_manager_v1_create(mp_display),
+ wlr_keyboard_shortcuts_inhibit_v1_create(mp_display)
+ };
}()),
#ifdef XWAYLAND
mp_xwayland(wlr_xwayland_create(mp_display, mp_compositor, 1)),
@@ -122,17 +135,9 @@ Server::Server(Model_ptr model)
mp_layer_shell(wlr_layer_shell_v1_create(mp_display)),
mp_xdg_shell(wlr_xdg_shell_create(mp_display)),
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)),
mp_server_decoration_manager(wlr_server_decoration_manager_create(mp_display)),
mp_xdg_decoration_manager(wlr_xdg_decoration_manager_v1_create(mp_display)),
mp_output_manager(wlr_output_manager_v1_create(mp_display)),
- mp_input_inhibit_manager(wlr_input_inhibit_manager_create(mp_display)),
- mp_keyboard_shortcuts_inhibit_manager(wlr_keyboard_shortcuts_inhibit_v1_create(mp_display)),
- mp_pointer_constraints(wlr_pointer_constraints_v1_create(mp_display)),
- mp_relative_pointer_manager(wlr_relative_pointer_manager_v1_create(mp_display)),
- 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 = Server::handle_output_layout_change }),
ml_output_manager_apply({ .notify = Server::handle_output_manager_apply }),
@@ -141,10 +146,6 @@ Server::Server(Model_ptr model)
ml_new_layer_shell_surface({ .notify = Server::handle_new_layer_shell_surface }),
ml_xdg_activation({ .notify = Server::handle_xdg_activation }),
ml_new_input({ .notify = Server::handle_new_input }),
- ml_inhibit_activate({ .notify = Server::handle_inhibit_activate }),
- ml_inhibit_deactivate({ .notify = Server::handle_inhibit_deactivate }),
- ml_idle_inhibitor_create({ .notify = Server::handle_idle_inhibitor_create }),
- ml_idle_inhibitor_destroy({ .notify = Server::handle_idle_inhibitor_destroy }),
ml_xdg_new_toplevel_decoration({ .notify = Server::handle_xdg_new_toplevel_decoration }),
#ifdef XWAYLAND
ml_xwayland_ready({ .notify = Server::handle_xwayland_ready }),
@@ -177,13 +178,10 @@ Server::Server(Model_ptr model)
wl_signal_add(&mp_output_layout->events.change, &ml_output_layout_change);
wl_signal_add(&mp_layer_shell->events.new_surface, &ml_new_layer_shell_surface);
wl_signal_add(&mp_xdg_shell->events.new_surface, &ml_new_xdg_surface);
- wl_signal_add(&mp_idle_inhibit_manager->events.new_inhibitor, &ml_idle_inhibitor_create);
wl_signal_add(&mp_xdg_decoration_manager->events.new_toplevel_decoration, &ml_xdg_new_toplevel_decoration);
wl_signal_add(&mp_backend->events.new_input, &ml_new_input);
wl_signal_add(&mp_output_manager->events.apply, &ml_output_manager_apply);
wl_signal_add(&mp_output_manager->events.test, &ml_output_manager_test);
- wl_signal_add(&mp_input_inhibit_manager->events.activate, &ml_inhibit_activate);
- wl_signal_add(&mp_input_inhibit_manager->events.deactivate, &ml_inhibit_deactivate);
// TODO: mp_keyboard_shortcuts_inhibit_manager signals
// TODO: mp_pointer_constraints signals
@@ -233,20 +231,45 @@ Server::run() noexcept
}
void
-Server::moveresize_view(View_ptr view, Region const& region, Extents const& extents, bool interactive)
+Server::terminate() noexcept
{
TRACE();
- wlr_scene_node_set_position(view->mp_scene, region.pos.x, region.pos.y);
- wlr_scene_node_set_position(view->mp_scene_surface, extents.left, extents.top);
- wlr_scene_rect_set_size(view->m_protrusions[0], region.dim.w, extents.top);
- wlr_scene_rect_set_size(view->m_protrusions[1], region.dim.w, extents.bottom);
- wlr_scene_rect_set_size(view->m_protrusions[2], extents.left, region.dim.h - extents.top - extents.bottom);
- wlr_scene_rect_set_size(view->m_protrusions[3], extents.right, region.dim.h - extents.top - extents.bottom);
- wlr_scene_node_set_position(&view->m_protrusions[0]->node, 0, 0);
- wlr_scene_node_set_position(&view->m_protrusions[1]->node, 0, region.dim.h - extents.bottom);
- wlr_scene_node_set_position(&view->m_protrusions[2]->node, 0, extents.top);
- wlr_scene_node_set_position(&view->m_protrusions[3]->node, region.dim.w - extents.right, extents.top);
+ wl_display_terminate(mp_display);
+}
+
+void
+Server::relinquish_focus()
+{
+ struct wlr_surface* focused_surface
+ = m_seat.mp_wlr_seat->keyboard_state.focused_surface;
+
+ if (focused_surface) {
+ if (wlr_surface_is_layer_surface(focused_surface)) {
+ struct wlr_layer_surface_v1* wlr_layer_surface
+ = wlr_layer_surface_v1_from_wlr_surface(focused_surface);
+
+ if (wlr_layer_surface->mapped && (
+ wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP ||
+ wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY))
+ {
+ return;
+ }
+ } else {
+ struct wlr_scene_node* node
+ = reinterpret_cast<struct wlr_scene_node*>(focused_surface->data);
+
+ struct wlr_xdg_surface* wlr_xdg_surface;
+ if (wlr_surface_is_xdg_surface(focused_surface)
+ && (wlr_xdg_surface = wlr_xdg_surface_from_wlr_surface(focused_surface))
+ && wlr_xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL)
+ {
+ wlr_xdg_toplevel_set_activated(wlr_xdg_surface, false);
+ }
+ }
+ }
+
+ wlr_seat_keyboard_notify_clear_focus(m_seat.mp_wlr_seat);
}
void
@@ -379,13 +402,13 @@ Server::handle_new_xdg_surface(struct wl_listener* listener, void* data)
&server->m_seat
);
- view->mp_scene = wlr_scene_xdg_surface_create(
- &server->mp_scene->node,
- xdg_surface
- );
+ /* view->mp_scene = wlr_scene_xdg_surface_create( */
+ /* &server->mp_scene->node, */
+ /* xdg_surface */
+ /* ); */
- view->mp_scene->data = view;
- xdg_surface->data = view->mp_scene;
+ /* view->mp_scene->data = view; */
+ /* xdg_surface->data = view->mp_scene; */
}
void
@@ -418,13 +441,13 @@ Server::handle_new_input(struct wl_listener* listener, void* data)
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);
+ = xkb_keymap_new_from_names(context, nullptr, 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);
+ wlr_seat_set_keyboard(server->m_seat.mp_wlr_seat, device);
break;
}
@@ -440,35 +463,7 @@ Server::handle_new_input(struct wl_listener* listener, void* data)
if (!server->m_seat.m_keyboards.empty())
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
- wlr_seat_set_capabilities(server->m_seat.mp_seat, caps);
-}
-
-void
-Server::handle_inhibit_activate(struct wl_listener*, void*)
-{
- TRACE();
-
-}
-
-void
-Server::handle_inhibit_deactivate(struct wl_listener*, void*)
-{
- TRACE();
-
-}
-
-void
-Server::handle_idle_inhibitor_create(struct wl_listener*, void*)
-{
- TRACE();
-
-}
-
-void
-Server::handle_idle_inhibitor_destroy(struct wl_listener*, void*)
-{
- TRACE();
-
+ wlr_seat_set_capabilities(server->m_seat.mp_wlr_seat, caps);
}
void
diff --git a/src/kranewl/tree/client.cc b/src/kranewl/tree/client.cc
@@ -28,28 +28,28 @@ Client::Client(
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{{}},
- m_free_decoration{{}},
- m_active_decoration{{}},
- 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_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_managed_since{std::chrono::steady_clock::now()},
m_outside_state{OutsideState::Unfocused}
diff --git a/src/kranewl/tree/output.cc b/src/kranewl/tree/output.cc
@@ -62,12 +62,11 @@ Output::handle_frame(struct wl_listener* listener, void*)
Output_ptr output = wl_container_of(listener, output, ml_frame);
- struct timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
-
if (!wlr_scene_output_commit(output->mp_wlr_scene_output))
return;
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
wlr_scene_output_send_frame_done(output->mp_wlr_scene_output, &now);
}
diff --git a/src/kranewl/tree/view.cc b/src/kranewl/tree/view.cc
@@ -45,9 +45,9 @@ View::View(
mp_workspace(nullptr),
mp_wlr_surface(wlr_surface),
m_alpha(1.f),
- m_tile_decoration(FREE_DECORATION),
- m_free_decoration(FREE_DECORATION),
- m_active_decoration(FREE_DECORATION),
+ m_tile_decoration{FREE_DECORATION},
+ m_free_decoration{FREE_DECORATION},
+ m_active_decoration{FREE_DECORATION},
m_minimum_dim({}),
m_preferred_dim({}),
m_free_region({}),
@@ -99,6 +99,9 @@ View::View(
mp_model(model),
mp_seat(seat),
mp_wlr_surface(wlr_surface),
+ m_tile_decoration({}, DEFAULT_COLOR_SCHEME),
+ m_free_decoration({}, DEFAULT_COLOR_SCHEME),
+ m_active_decoration({}, DEFAULT_COLOR_SCHEME),
ml_foreign_activate_request({ .notify = handle_foreign_activate_request }),
ml_foreign_fullscreen_request({ .notify = handle_foreign_fullscreen_request }),
ml_foreign_close_request({ .notify = handle_foreign_close_request }),
@@ -120,7 +123,7 @@ set_view_pid(View_ptr view)
struct wl_client* client
= wl_resource_get_client(view->mp_wlr_surface->resource);
- wl_client_get_credentials(client, &pid, NULL, NULL);
+ wl_client_get_credentials(client, &pid, nullptr, nullptr);
view->m_pid = pid;
break;
@@ -140,8 +143,7 @@ set_view_pid(View_ptr view)
}
void
-View::map_view(
- View_ptr view,
+View::map(
struct wlr_surface* wlr_surface,
bool fullscreen,
struct wlr_output* fullscreen_output,
@@ -150,50 +152,56 @@ View::map_view(
{
TRACE();
- Server_ptr server = view->mp_server;
- Model_ptr model = view->mp_model;
+ Server_ptr server = mp_server;
+ Model_ptr model = mp_model;
- view->mp_wlr_surface = wlr_surface;
- set_view_pid(view);
+ mp_wlr_surface = wlr_surface;
+ set_view_pid(this);
- view->mp_scene = &wlr_scene_tree_create(view->mp_server->m_layers[Layer::Tile])->node;
- view->mp_wlr_surface->data = view->mp_scene_surface = view->m_type == View::Type::XDGShell
+ mp_scene = &wlr_scene_tree_create(mp_server->m_layers[Layer::Tile])->node;
+ mp_wlr_surface->data = mp_scene_surface = m_type == View::Type::XDGShell
? wlr_scene_xdg_surface_create(
- view->mp_scene,
- reinterpret_cast<XDGView_ptr>(view)->mp_wlr_xdg_surface
+ mp_scene,
+ reinterpret_cast<XDGView_ptr>(this)->mp_wlr_xdg_surface
)
- : wlr_scene_subsurface_tree_create(view->mp_scene, view->mp_wlr_surface);
- view->mp_scene_surface->data = view;
+ : wlr_scene_subsurface_tree_create(mp_scene, mp_wlr_surface);
+ mp_scene_surface->data = this;
wlr_scene_node_reparent(
- view->mp_scene,
- server->m_layers[view->m_floating ? Layer::Free : Layer::Tile]
+ mp_scene,
+ server->m_layers[m_floating ? Layer::Free : Layer::Tile]
);
- // TODO: globalize
- static const float border_rgba[4] = {0.5, 0.5, 0.5, 1.0};
-
for (std::size_t i = 0; i < 4; ++i) {
- view->m_protrusions[i] = wlr_scene_rect_create(view->mp_scene, 0, 0, border_rgba);
- view->m_protrusions[i]->node.data = view;
- wlr_scene_rect_set_color(view->m_protrusions[i], border_rgba);
- wlr_scene_node_lower_to_bottom(&view->m_protrusions[i]->node);
+ m_protrusions[i] = wlr_scene_rect_create(
+ mp_scene,
+ 0,
+ 0,
+ m_active_decoration.colorscheme.unfocused.values
+ );
+ m_protrusions[i]->node.data = this;
+ wlr_scene_rect_set_color(
+ m_protrusions[i],
+ m_active_decoration.colorscheme.unfocused.values
+ );
+ wlr_scene_node_lower_to_bottom(&m_protrusions[i]->node);
}
if (fullscreen_output && fullscreen_output->data) {
Output_ptr output = reinterpret_cast<Output_ptr>(fullscreen_output->data);
}
- model->move_view_to_focused_output(view);
+ model->move_view_to_focused_output(this);
+ focus(true);
}
-
void
-View::unmap_view(View_ptr view)
+View::unmap()
{
TRACE();
- wlr_scene_node_destroy(view->mp_scene);
+ wlr_scene_node_destroy(mp_scene_surface);
+ wlr_scene_node_destroy(mp_scene);
}
static uint32_t
diff --git a/src/kranewl/tree/xdg_view.cc b/src/kranewl/tree/xdg_view.cc
@@ -11,6 +11,9 @@
#define namespace namespace_
#define static
extern "C" {
+#include <wlr/types/wlr_idle.h>
+#include <wlr/types/wlr_idle_inhibit_v1.h>
+#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_xdg_shell.h>
}
@@ -59,6 +62,110 @@ XDGView::~XDGView()
{}
void
+XDGView::focus(bool raise)
+{
+ TRACE();
+
+ struct wlr_surface* focused_surface
+ = mp_seat->mp_wlr_seat->keyboard_state.focused_surface;
+
+ if (raise)
+ wlr_scene_node_raise_to_top(mp_scene);
+
+ if (focused_surface == mp_wlr_surface)
+ return;
+
+ mp_model->focus_view(this);
+
+ for (std::size_t i = 0; i < 4; ++i)
+ wlr_scene_rect_set_color(
+ m_protrusions[i],
+ m_active_decoration.colorscheme.focused.values
+ );
+
+ if (focused_surface && focused_surface != mp_wlr_surface) {
+ if (wlr_surface_is_layer_surface(focused_surface)) {
+ struct wlr_layer_surface_v1* wlr_layer_surface
+ = wlr_layer_surface_v1_from_wlr_surface(focused_surface);
+
+ if (wlr_layer_surface->mapped && (
+ wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP ||
+ wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY))
+ {
+ return;
+ }
+ } else {
+ struct wlr_scene_node* node
+ = reinterpret_cast<struct wlr_scene_node*>(focused_surface->data);
+
+ if (focused_surface->role_data && node->data)
+ for (std::size_t i = 0; i < 4; ++i)
+ wlr_scene_rect_set_color(
+ m_protrusions[i],
+ m_active_decoration.colorscheme.unfocused.values
+ );
+
+ struct wlr_xdg_surface* wlr_xdg_surface;
+ if (wlr_surface_is_xdg_surface(focused_surface)
+ && (wlr_xdg_surface = wlr_xdg_surface_from_wlr_surface(focused_surface))
+ && wlr_xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL)
+ {
+ wlr_xdg_toplevel_set_activated(wlr_xdg_surface, false);
+ }
+ }
+ }
+
+ wlr_idle_set_enabled(
+ mp_seat->mp_idle,
+ mp_seat->mp_wlr_seat,
+ wl_list_empty(&mp_seat->mp_idle_inhibit_manager->inhibitors)
+ );
+
+ struct wlr_keyboard* keyboard = wlr_seat_get_keyboard(mp_seat->mp_wlr_seat);
+ if (keyboard)
+ wlr_seat_keyboard_notify_enter(
+ mp_seat->mp_wlr_seat,
+ mp_wlr_surface,
+ keyboard->keycodes,
+ keyboard->num_keycodes,
+ &keyboard->modifiers
+ );
+ else
+ wlr_seat_keyboard_notify_enter(
+ mp_seat->mp_wlr_seat,
+ mp_wlr_surface,
+ nullptr,
+ 0,
+ nullptr
+ );
+
+ wlr_xdg_toplevel_set_activated(mp_wlr_xdg_surface, true);
+}
+
+void
+XDGView::moveresize(Region const& region, Extents const& extents, bool interactive)
+{
+ TRACE();
+
+ wlr_scene_node_set_position(mp_scene, region.pos.x, region.pos.y);
+ wlr_scene_node_set_position(mp_scene_surface, extents.left, extents.top);
+ wlr_scene_rect_set_size(m_protrusions[0], region.dim.w, extents.top);
+ wlr_scene_rect_set_size(m_protrusions[1], region.dim.w, extents.bottom);
+ wlr_scene_rect_set_size(m_protrusions[2], extents.left, region.dim.h - extents.top - extents.bottom);
+ wlr_scene_rect_set_size(m_protrusions[3], extents.right, region.dim.h - extents.top - extents.bottom);
+ wlr_scene_node_set_position(&m_protrusions[0]->node, 0, 0);
+ wlr_scene_node_set_position(&m_protrusions[1]->node, 0, region.dim.h - extents.bottom);
+ wlr_scene_node_set_position(&m_protrusions[2]->node, 0, extents.top);
+ wlr_scene_node_set_position(&m_protrusions[3]->node, region.dim.w - extents.right, extents.top);
+
+ m_resize = wlr_xdg_toplevel_set_size(
+ mp_wlr_xdg_surface,
+ region.dim.w - extents.left - extents.right,
+ region.dim.h - extents.top - extents.bottom
+ );
+}
+
+void
XDGView::handle_foreign_activate_request(struct wl_listener* listener, void* data)
{
TRACE();
@@ -196,8 +303,7 @@ XDGView::handle_map(struct wl_listener* listener, void* data)
.h = state.min_height
};
- View::map_view(
- view,
+ view->map(
wlr_xdg_toplevel->base->surface,
wlr_xdg_toplevel->requested.fullscreen,
wlr_xdg_toplevel->requested.fullscreen_output,
@@ -226,7 +332,8 @@ XDGView::handle_unmap(struct wl_listener* listener, void* data)
XDGView_ptr view = wl_container_of(listener, view, ml_unmap);
- View::unmap_view(view);
+ view->unmap();
+ view->mp_model->unmap_view(view);
}
void
diff --git a/src/kranewl/tree/xwayland_view.cc b/src/kranewl/tree/xwayland_view.cc
@@ -59,6 +59,17 @@ XWaylandView::XWaylandView(
XWaylandView::~XWaylandView()
{}
+void
+XWaylandView::focus(bool raise)
+{}
+
+void
+XWaylandView::moveresize(Region const& region, Extents const& extents, bool interactive)
+{
+ TRACE();
+
+}
+
XWaylandUnmanaged::XWaylandUnmanaged(struct wlr_xwayland_surface* wlr_xwayland_surface)
: mp_wlr_xwayland_surface(wlr_xwayland_surface)
{}