commit 81b4be77799991f14b2f42a61f3e972918dda24e
parent a619f30fd0f4a4183bf3969d446ca9d1027eeb2b
Author: deurzen <m.deurzen@tum.de>
Date: Mon, 23 May 2022 00:51:56 +0200
adds initial view mapping functionality
Diffstat:
9 files changed, 155 insertions(+), 10 deletions(-)
diff --git a/include/kranewl/server.hh b/include/kranewl/server.hh
@@ -41,6 +41,7 @@ private:
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*);
static void handle_xdg_toplevel_destroy(struct wl_listener*, void*);
@@ -104,6 +105,7 @@ private:
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;
struct wl_listener ml_new_xwayland_surface;
diff --git a/include/kranewl/tree/view.hh b/include/kranewl/tree/view.hh
@@ -23,7 +23,7 @@ typedef class Output* Output_ptr;
typedef class Context* Context_ptr;
typedef class Workspace* Workspace_ptr;
typedef struct XDGView* XDGView_ptr;
-#if XWAYLAND
+#ifdef XWAYLAND
typedef struct XWaylandView* XWaylandView_ptr;
#endif
typedef struct View* View_ptr;
@@ -34,7 +34,7 @@ typedef struct View {
enum class Type {
XDGShell,
-#if XWAYLAND
+#ifdef XWAYLAND
XWayland,
#endif
};
@@ -48,13 +48,14 @@ typedef struct View {
Output_ptr,
Context_ptr,
Workspace_ptr,
+ struct wlr_surface*,
void(*)(wl_listener*, void*),
void(*)(wl_listener*, void*),
void(*)(wl_listener*, void*),
void(*)(wl_listener*, void*),
void(*)(wl_listener*, void*)
);
-#if XWAYLAND
+#ifdef XWAYLAND
View(
XWaylandView_ptr,
Uid,
@@ -64,6 +65,7 @@ typedef struct View {
Output_ptr,
Context_ptr,
Workspace_ptr,
+ struct wlr_surface*,
void(*)(wl_listener*, void*),
void(*)(wl_listener*, void*),
void(*)(wl_listener*, void*),
@@ -74,6 +76,8 @@ typedef struct View {
virtual ~View();
+ static void map_view(View_ptr, struct wlr_surface*, bool, struct wlr_output*, bool);
+
static bool
is_free(View_ptr view)
{
@@ -93,6 +97,7 @@ typedef struct View {
Context_ptr mp_context;
Workspace_ptr mp_workspace;
+ struct wlr_surface* mp_wlr_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
@@ -109,7 +114,7 @@ typedef struct View {
Decoration m_free_decoration;
Decoration m_active_decoration;
- Region m_preferred_region;
+ Dim m_preferred_dim;
Region m_free_region;
Region m_tile_region;
Region m_active_region;
diff --git a/include/kranewl/tree/xwayland_view.hh b/include/kranewl/tree/xwayland_view.hh
@@ -10,7 +10,7 @@ typedef class Output* Output_ptr;
typedef class Context* Context_ptr;
typedef class Workspace* Workspace_ptr;
-#if XWAYLAND
+#ifdef XWAYLAND
typedef struct XWaylandView final : public View {
XWaylandView(
struct wlr_xwayland_surface*,
diff --git a/include/version.hh b/include/version.hh
@@ -1 +1 @@
-#define VERSION "master/b7cfa06+"
-\ No newline at end of file
+#define VERSION "master/a619f30+"
+\ No newline at end of file
diff --git a/src/kranewl/model.cc b/src/kranewl/model.cc
@@ -17,7 +17,6 @@
#include <kranewl/workspace.hh>
#include <spdlog/spdlog.h>
-#include <spdlog/fmt/bin_to_hex.h>
#include <iomanip>
diff --git a/src/kranewl/server.cc b/src/kranewl/server.cc
@@ -9,7 +9,9 @@
#include <kranewl/tree/output.hh>
#include <kranewl/tree/view.hh>
#include <kranewl/tree/xdg_view.hh>
+#ifdef XWAYLAND
#include <kranewl/tree/xwayland_view.hh>
+#endif
#include <spdlog/spdlog.h>
@@ -134,6 +136,7 @@ Server::Server(Model_ptr model)
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 }),
ml_new_xwayland_surface({ .notify = Server::handle_new_xwayland_surface }),
@@ -166,6 +169,7 @@ Server::Server(Model_ptr model)
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);
@@ -423,6 +427,20 @@ Server::handle_idle_inhibitor_destroy(struct wl_listener*, void*)
}
void
+Server::handle_xdg_new_toplevel_decoration(struct wl_listener*, void* data)
+{
+ TRACE();
+
+ struct wlr_xdg_toplevel_decoration_v1* decoration
+ = reinterpret_cast<struct wlr_xdg_toplevel_decoration_v1*>(data);
+
+ wlr_xdg_toplevel_decoration_v1_set_mode(
+ decoration,
+ WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE
+ );
+}
+
+void
Server::handle_xdg_toplevel_map(struct wl_listener*, void*)
{
TRACE();
diff --git a/src/kranewl/tree/view.cc b/src/kranewl/tree/view.cc
@@ -1,5 +1,12 @@
+#include <trace.hh>
+
#include <kranewl/tree/view.hh>
+extern "C" {
+#include <sys/types.h>
+#include <wlr/types/wlr_xdg_shell.h>
+}
+
View::View(
XDGView_ptr,
Uid uid,
@@ -9,6 +16,7 @@ View::View(
Output_ptr output,
Context_ptr context,
Workspace_ptr workspace,
+ struct wlr_surface* wlr_surface,
void(*handle_foreign_activate_request)(wl_listener*, void*),
void(*handle_foreign_fullscreen_request)(wl_listener*, void*),
void(*handle_foreign_close_request)(wl_listener*, void*),
@@ -23,6 +31,32 @@ View::View(
mp_output(output),
mp_context(context),
mp_workspace(workspace),
+ 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_preferred_dim({}),
+ m_free_region({}),
+ m_tile_region({}),
+ m_active_region({}),
+ m_previous_region({}),
+ m_inner_region({}),
+ m_focused(false),
+ m_mapped(false),
+ m_managed(true),
+ m_urgent(false),
+ m_floating(false),
+ m_fullscreen(false),
+ m_scratchpad(false),
+ m_contained(false),
+ m_invincible(false),
+ m_sticky(false),
+ m_iconifyable(true),
+ m_iconified(false),
+ m_disowned(false),
+ m_last_focused(std::chrono::steady_clock::now()),
+ m_managed_since(std::chrono::steady_clock::now()),
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 }),
@@ -32,7 +66,7 @@ View::View(
wl_signal_init(&m_events.unmap);
}
-#if XWAYLAND
+#ifdef XWAYLAND
View::View(
XWaylandView_ptr,
Uid uid,
@@ -42,6 +76,7 @@ View::View(
Output_ptr output,
Context_ptr context,
Workspace_ptr workspace,
+ struct wlr_surface* wlr_surface,
void(*handle_foreign_activate_request)(wl_listener*, void*),
void(*handle_foreign_fullscreen_request)(wl_listener*, void*),
void(*handle_foreign_close_request)(wl_listener*, void*),
@@ -56,6 +91,7 @@ View::View(
mp_output(output),
mp_context(context),
mp_workspace(workspace),
+ mp_wlr_surface(wlr_surface),
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 }),
@@ -67,6 +103,48 @@ View::View(
View::~View()
{}
+static inline void
+retrieve_view_pid(View_ptr view)
+{
+ switch (view->m_type) {
+ case View::Type::XDGShell:
+ {
+ pid_t pid;
+ struct wl_client* client
+ = wl_resource_get_client(view->mp_wlr_surface->resource);
+
+ wl_client_get_credentials(client, &pid, NULL, NULL);
+ view->m_pid = pid;
+ }
+ break;
+#if HAVE_XWAYLAND
+ case View::Type::XWayland:
+ {
+ struct wlr_xwayland_surface* wlr_xwayland_surface
+ = wlr_xwayland_surface_from_wlr_surface(view->mp_wlr_surface);
+ view->m_pid = wlr_xwayland_surface->pid;
+ }
+ break;
+#endif
+ default: break;
+ }
+}
+
+void
+View::map_view(
+ View_ptr view,
+ struct wlr_surface* wlr_surface,
+ bool fullscreen,
+ struct wlr_output* fullscreen_output,
+ bool decorations
+)
+{
+ TRACE();
+
+ view->mp_wlr_surface = wlr_surface;
+ retrieve_view_pid(view);
+}
+
ViewChild::ViewChild(SubsurfaceViewChild_ptr)
: m_type(Type::Subsurface)
{}
diff --git a/src/kranewl/tree/xdg_view.cc b/src/kranewl/tree/xdg_view.cc
@@ -25,6 +25,7 @@ XDGView::XDGView(
output,
context,
workspace,
+ wlr_xdg_surface->surface,
XDGView::handle_foreign_activate_request,
XDGView::handle_foreign_fullscreen_request,
XDGView::handle_foreign_close_request,
@@ -141,6 +142,35 @@ XDGView::handle_map(struct wl_listener* listener, void* data)
{
TRACE();
+ XDGView_ptr view = wl_container_of(listener, view, ml_map);
+ struct wlr_xdg_toplevel* wlr_xdg_toplevel = view->mp_wlr_xdg_toplevel;
+
+ view->m_mapped = true;
+ view->m_preferred_dim = Dim{
+ .w = wlr_xdg_toplevel->base->current.geometry.width,
+ .h = wlr_xdg_toplevel->base->current.geometry.height,
+ };
+
+ if (!view->m_preferred_dim.w && !view->m_preferred_dim.h) {
+ view->m_preferred_dim.w = wlr_xdg_toplevel->base->surface->current.width;
+ view->m_preferred_dim.h = wlr_xdg_toplevel->base->surface->current.height;
+ }
+
+ View::map_view(
+ view,
+ wlr_xdg_toplevel->base->surface,
+ wlr_xdg_toplevel->requested.fullscreen,
+ wlr_xdg_toplevel->requested.fullscreen_output,
+ false // TODO: determine if client has decorations
+ );
+
+ wl_signal_add(&wlr_xdg_toplevel->base->surface->events.commit, &view->ml_commit);
+ wl_signal_add(&wlr_xdg_toplevel->base->events.new_popup, &view->ml_new_popup);
+ wl_signal_add(&wlr_xdg_toplevel->events.request_fullscreen, &view->ml_request_fullscreen);
+ wl_signal_add(&wlr_xdg_toplevel->events.request_move, &view->ml_request_move);
+ wl_signal_add(&wlr_xdg_toplevel->events.request_resize, &view->ml_request_resize);
+ wl_signal_add(&wlr_xdg_toplevel->events.set_title, &view->ml_set_title);
+ wl_signal_add(&wlr_xdg_toplevel->events.set_app_id, &view->ml_set_app_id);
}
void
diff --git a/src/kranewl/tree/xwayland_view.cc b/src/kranewl/tree/xwayland_view.cc
@@ -1,9 +1,21 @@
+#ifdef XWAYLAND
#include <trace.hh>
#include <kranewl/tree/view.hh>
#include <kranewl/tree/xwayland_view.hh>
-#if XWAYLAND
+// https://github.com/swaywm/wlroots/issues/682
+#include <pthread.h>
+#define class class_
+#define namespace namespace_
+#define static
+extern "C" {
+#include <wlr/xwayland.h>
+}
+#undef static
+#undef class
+#undef namespace
+
XWaylandView::XWaylandView(
struct wlr_xwayland_surface* wlr_xwayland_surface,
Server_ptr server,
@@ -22,6 +34,7 @@ XWaylandView::XWaylandView(
output,
context,
workspace,
+ wlr_xwayland_surface->surface,
XWaylandView::handle_foreign_activate_request,
XWaylandView::handle_foreign_fullscreen_request,
XWaylandView::handle_foreign_close_request,