mirror of
https://github.com/labwc/labwc.git
synced 2026-03-19 05:33:53 -04:00
Decorations: handle results of kde-server-decoration negotiations
This commit is contained in:
parent
5ee2ec7fff
commit
ef30e3750d
6 changed files with 160 additions and 36 deletions
|
|
@ -3,7 +3,13 @@
|
||||||
#define __LAB_DECORATIONS_H
|
#define __LAB_DECORATIONS_H
|
||||||
|
|
||||||
struct server;
|
struct server;
|
||||||
|
struct view;
|
||||||
|
struct wlr_surface;
|
||||||
|
|
||||||
|
void kde_server_decoration_init(struct server *server);
|
||||||
void xdg_server_decoration_init(struct server *server);
|
void xdg_server_decoration_init(struct server *server);
|
||||||
|
|
||||||
|
void kde_server_decoration_update_default(void);
|
||||||
|
void kde_server_decoration_set_view(struct view *view, struct wlr_surface *surface);
|
||||||
|
|
||||||
#endif /* __LAB_DECORATIONS_H */
|
#endif /* __LAB_DECORATIONS_H */
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@
|
||||||
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||||
#include <wlr/types/wlr_pointer_gestures_v1.h>
|
#include <wlr/types/wlr_pointer_gestures_v1.h>
|
||||||
#include <wlr/types/wlr_seat.h>
|
#include <wlr/types/wlr_seat.h>
|
||||||
#include <wlr/types/wlr_server_decoration.h>
|
|
||||||
#include <wlr/types/wlr_subcompositor.h>
|
#include <wlr/types/wlr_subcompositor.h>
|
||||||
#include <wlr/types/wlr_xcursor_manager.h>
|
#include <wlr/types/wlr_xcursor_manager.h>
|
||||||
#include <wlr/types/wlr_xdg_activation_v1.h>
|
#include <wlr/types/wlr_xdg_activation_v1.h>
|
||||||
|
|
@ -220,6 +219,7 @@ struct server {
|
||||||
struct wl_listener new_xdg_surface;
|
struct wl_listener new_xdg_surface;
|
||||||
struct wl_listener new_layer_surface;
|
struct wl_listener new_layer_surface;
|
||||||
|
|
||||||
|
struct wl_listener kde_server_decoration;
|
||||||
struct wl_listener xdg_toplevel_decoration;
|
struct wl_listener xdg_toplevel_decoration;
|
||||||
#if HAVE_XWAYLAND
|
#if HAVE_XWAYLAND
|
||||||
struct wlr_xwayland *xwayland;
|
struct wlr_xwayland *xwayland;
|
||||||
|
|
|
||||||
132
src/decorations/kde-deco.c
Normal file
132
src/decorations/kde-deco.c
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
#include <assert.h>
|
||||||
|
#include <wlr/types/wlr_server_decoration.h>
|
||||||
|
#include "common/list.h"
|
||||||
|
#include "common/mem.h"
|
||||||
|
#include "decorations.h"
|
||||||
|
#include "labwc.h"
|
||||||
|
#include "view.h"
|
||||||
|
|
||||||
|
static struct wl_list decorations;
|
||||||
|
static struct wlr_server_decoration_manager *kde_deco_mgr;
|
||||||
|
|
||||||
|
struct kde_deco {
|
||||||
|
struct wl_list link; /* decorations */
|
||||||
|
struct wlr_server_decoration *wlr_kde_decoration;
|
||||||
|
struct view *view;
|
||||||
|
struct wl_listener mode;
|
||||||
|
struct wl_listener destroy;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_destroy(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct kde_deco *kde_deco = wl_container_of(listener, kde_deco, destroy);
|
||||||
|
wl_list_remove(&kde_deco->destroy.link);
|
||||||
|
wl_list_remove(&kde_deco->mode.link);
|
||||||
|
wl_list_remove(&kde_deco->link);
|
||||||
|
free(kde_deco);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_mode(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct kde_deco *kde_deco = wl_container_of(listener, kde_deco, mode);
|
||||||
|
if (!kde_deco->view) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum wlr_server_decoration_manager_mode client_mode =
|
||||||
|
kde_deco->wlr_kde_decoration->mode;
|
||||||
|
|
||||||
|
switch (client_mode) {
|
||||||
|
case WLR_SERVER_DECORATION_MANAGER_MODE_SERVER:
|
||||||
|
kde_deco->view->ssd_preference = LAB_SSD_PREF_SERVER;
|
||||||
|
break;
|
||||||
|
case WLR_SERVER_DECORATION_MANAGER_MODE_NONE:
|
||||||
|
case WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT:
|
||||||
|
kde_deco->view->ssd_preference = LAB_SSD_PREF_CLIENT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wlr_log(WLR_ERROR, "Unspecified kde decoration variant "
|
||||||
|
"requested: %u", client_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
view_set_decorations(kde_deco->view,
|
||||||
|
kde_deco->view->ssd_preference == LAB_SSD_PREF_SERVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_new_server_decoration(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct wlr_server_decoration *wlr_deco = data;
|
||||||
|
struct kde_deco *kde_deco = znew(*kde_deco);
|
||||||
|
kde_deco->wlr_kde_decoration = wlr_deco;
|
||||||
|
|
||||||
|
if (wlr_surface_is_xdg_surface(wlr_deco->surface)) {
|
||||||
|
/*
|
||||||
|
* Depending on the application event flow, the supplied
|
||||||
|
* wlr_surface may already have been set up as a xdg_surface
|
||||||
|
* or not (e.g. for GTK4). In the second case, the xdg.c
|
||||||
|
* new_surface handler will try to set the view via
|
||||||
|
* kde_server_decoration_set_view().
|
||||||
|
*/
|
||||||
|
struct wlr_xdg_surface *xdg_surface =
|
||||||
|
wlr_xdg_surface_from_wlr_surface(wlr_deco->surface);
|
||||||
|
if (xdg_surface && xdg_surface->data) {
|
||||||
|
kde_deco->view = (struct view *)xdg_surface->data;
|
||||||
|
handle_mode(&kde_deco->mode, wlr_deco);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_signal_add(&wlr_deco->events.destroy, &kde_deco->destroy);
|
||||||
|
kde_deco->destroy.notify = handle_destroy;
|
||||||
|
|
||||||
|
wl_signal_add(&wlr_deco->events.mode, &kde_deco->mode);
|
||||||
|
kde_deco->mode.notify = handle_mode;
|
||||||
|
|
||||||
|
wl_list_append(&decorations, &kde_deco->link);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kde_server_decoration_set_view(struct view *view, struct wlr_surface *surface)
|
||||||
|
{
|
||||||
|
struct kde_deco *kde_deco;
|
||||||
|
wl_list_for_each(kde_deco, &decorations, link) {
|
||||||
|
if (kde_deco->wlr_kde_decoration->surface == surface) {
|
||||||
|
if (!kde_deco->view) {
|
||||||
|
kde_deco->view = view;
|
||||||
|
handle_mode(&kde_deco->mode, kde_deco->wlr_kde_decoration);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kde_server_decoration_update_default(void)
|
||||||
|
{
|
||||||
|
assert(kde_deco_mgr);
|
||||||
|
wlr_server_decoration_manager_set_default_mode(kde_deco_mgr,
|
||||||
|
rc.xdg_shell_server_side_deco
|
||||||
|
? WLR_SERVER_DECORATION_MANAGER_MODE_SERVER
|
||||||
|
: WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kde_server_decoration_init(struct server *server)
|
||||||
|
{
|
||||||
|
assert(!kde_deco_mgr);
|
||||||
|
kde_deco_mgr = wlr_server_decoration_manager_create(server->wl_display);
|
||||||
|
if (!kde_deco_mgr) {
|
||||||
|
wlr_log(WLR_ERROR, "unable to create the kde server deco manager");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_list_init(&decorations);
|
||||||
|
kde_server_decoration_update_default();
|
||||||
|
|
||||||
|
wl_signal_add(&kde_deco_mgr->events.new_decoration, &server->kde_server_decoration);
|
||||||
|
server->kde_server_decoration.notify = handle_new_server_decoration;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
labwc_sources += files(
|
labwc_sources += files(
|
||||||
|
'kde-deco.c',
|
||||||
'xdg-deco.c',
|
'xdg-deco.c',
|
||||||
)
|
)
|
||||||
|
|
|
||||||
13
src/server.c
13
src/server.c
|
|
@ -53,6 +53,7 @@ reload_config_and_theme(void)
|
||||||
menu_reconfigure(g_server);
|
menu_reconfigure(g_server);
|
||||||
seat_reconfigure(g_server);
|
seat_reconfigure(g_server);
|
||||||
regions_reconfigure(g_server);
|
regions_reconfigure(g_server);
|
||||||
|
kde_server_decoration_update_default();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -310,18 +311,8 @@ server_init(struct server *server)
|
||||||
wl_signal_add(&server->xdg_shell->events.new_surface,
|
wl_signal_add(&server->xdg_shell->events.new_surface,
|
||||||
&server->new_xdg_surface);
|
&server->new_xdg_surface);
|
||||||
|
|
||||||
/* Disable CSD */
|
kde_server_decoration_init(server);
|
||||||
xdg_server_decoration_init(server);
|
xdg_server_decoration_init(server);
|
||||||
struct wlr_server_decoration_manager *deco_mgr = NULL;
|
|
||||||
deco_mgr = wlr_server_decoration_manager_create(server->wl_display);
|
|
||||||
if (!deco_mgr) {
|
|
||||||
wlr_log(WLR_ERROR, "unable to create the server deco manager");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
wlr_server_decoration_manager_set_default_mode(
|
|
||||||
deco_mgr, rc.xdg_shell_server_side_deco
|
|
||||||
? WLR_SERVER_DECORATION_MANAGER_MODE_SERVER
|
|
||||||
: WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT);
|
|
||||||
|
|
||||||
server->xdg_activation = wlr_xdg_activation_v1_create(server->wl_display);
|
server->xdg_activation = wlr_xdg_activation_v1_create(server->wl_display);
|
||||||
if (!server->xdg_activation) {
|
if (!server->xdg_activation) {
|
||||||
|
|
|
||||||
42
src/xdg.c
42
src/xdg.c
|
|
@ -1,6 +1,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "common/mem.h"
|
#include "common/mem.h"
|
||||||
|
#include "decorations.h"
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
|
@ -48,38 +49,22 @@ handle_new_xdg_popup(struct wl_listener *listener, void *data)
|
||||||
static bool
|
static bool
|
||||||
has_ssd(struct view *view)
|
has_ssd(struct view *view)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* view->ssd_preference may be set by the decoration implementation
|
||||||
|
* e.g. src/decorations/xdg-deco.c or src/decorations/kde-deco.c.
|
||||||
|
*/
|
||||||
switch (view->ssd_preference) {
|
switch (view->ssd_preference) {
|
||||||
case LAB_SSD_PREF_SERVER:
|
case LAB_SSD_PREF_SERVER:
|
||||||
return true;
|
return true;
|
||||||
case LAB_SSD_PREF_CLIENT:
|
case LAB_SSD_PREF_CLIENT:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rc.xdg_shell_server_side_deco) {
|
|
||||||
/*
|
/*
|
||||||
* User prefers client side decorations and
|
* We don't know anything about the client preference
|
||||||
* the view didn't negotiate server side ones.
|
* so fall back to core.decoration settings in rc.xml
|
||||||
*/
|
*/
|
||||||
return false;
|
return rc.xdg_shell_server_side_deco;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Some XDG shells refuse to disable CSD in which case their
|
|
||||||
* geometry.{x,y} seems to be greater than zero. We filter on that
|
|
||||||
* on the assumption that this will remain true.
|
|
||||||
*
|
|
||||||
* TODO: Replace this with a proper implementation of
|
|
||||||
* the KDE decoration variant as can be seen at
|
|
||||||
* https://github.com/swaywm/sway/blob/master/sway/decoration.c
|
|
||||||
*/
|
|
||||||
struct wlr_xdg_surface_state *current =
|
|
||||||
&xdg_surface_from_view(view)->current;
|
|
||||||
if (current->geometry.x || current->geometry.y) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -560,9 +545,18 @@ xdg_surface_new(struct wl_listener *listener, void *data)
|
||||||
node_descriptor_create(&view->scene_tree->node,
|
node_descriptor_create(&view->scene_tree->node,
|
||||||
LAB_NODE_DESC_VIEW, view);
|
LAB_NODE_DESC_VIEW, view);
|
||||||
|
|
||||||
/* In support of xdg_toplevel_decoration */
|
/* In support of xdg_toplevel_decoration and kde_server_decoration */
|
||||||
xdg_surface->data = view;
|
xdg_surface->data = view;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GTK4 initializes the decorations on the wl_surface before
|
||||||
|
* converting it into a xdg surface. This call takes care of
|
||||||
|
* connecting the view to an existing decoration. If there
|
||||||
|
* is no existing decoration object available for the
|
||||||
|
* wl_surface, this call is a no-op.
|
||||||
|
*/
|
||||||
|
kde_server_decoration_set_view(view, xdg_surface->surface);
|
||||||
|
|
||||||
/* In support of xdg popups */
|
/* In support of xdg popups */
|
||||||
xdg_surface->surface->data = tree;
|
xdg_surface->surface->data = tree;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue