Merge branch 'master' into menu-accelerators

This commit is contained in:
Alex Chernika 2026-04-15 00:54:15 +02:00
commit 5a6e17444e
No known key found for this signature in database
GPG key ID: 6029FAD8ABFB076A
19 changed files with 539 additions and 43 deletions

View file

@ -424,6 +424,13 @@ Actions are used in menus and keyboard/mouse bindings.
Toggle the screen magnifier on or off at the last magnification level
used.
*<action name="ToggleShowDesktop" />*
Minimize all windows in the current workspace so that the desktop becomes
visible. On calling the action again the hidden windows are unminimized,
provided that - since the initial `ShowDesktop` - (a) no windows have been
unminimized; (b) workspaces have not been switched; and (c) no new
applications have been started.
*<action name="ZoomIn">*++
*<action name="ZoomOut">*
Increase or decrease the magnification level for the screen magnifier.
@ -436,6 +443,10 @@ Actions are used in menus and keyboard/mouse bindings.
If used as the only action for a binding: clear an earlier defined
binding.
*<action name="DebugToggleKeyStateIndicator" />*
Toggle visibility of key-state on-screen display (OSD). Note: This is for
debugging purposes only.
# CONDITIONAL ACTIONS
Actions that execute other actions. Used in keyboard/mouse bindings.

View file

@ -760,7 +760,8 @@ References:
Stores the keyboard layout either globally or per window and restores
it when switching back to the window. Default is global.
*<keyboard><keybind key="" layoutDependent="" onRelease="" allowWhenLocked="">*
*<keyboard><keybind key="" layoutDependent="" onRelease="" allowWhenLocked=""
overrideInhibition="">*
Define a *key* binding in the format *modifier-key*, where supported
modifiers are:
- S (shift)
@ -808,6 +809,11 @@ References:
*allowWhenLocked* [yes|no]
Make this keybind work even if the screen is locked. Default is no.
*overrideInhibition* [yes|no]
Make this keybind work even if the view inhibits keybinds. Default is no.
This can be used to prevent W-Tab and similar keybinds from being
delivered to Virtual Machines, VNC clients or nested compositors.
*onRelease* [yes|no]
When yes, fires the keybind action when the key or key
combination is released, rather than first pressed. This is useful to
@ -1445,6 +1451,52 @@ situation.
Whether to apply a bilinear filter to the magnified image, or
just to use nearest-neighbour. Default is true - bilinear filtered.
## PRIVILEGED INTERFACES
Labwc supports a small set of privileged wayland interfaces. All of these
interfaces are enabled by default for applications unless they are running
via a sandbox environment supporting the security-context-v1 protocol.
Security conscious users are suggested to use a sandbox framework to run
potentially untrusted applications as it additionally limits access to the
filesystem (including labwc configuration) and other services like dbus.
In addition to that, privileged protocols can be restricted for non-sandboxed
clients by defining a `<privilegedInterfaces>` block:
```
<privilegedInterfaces>
<allow>zwlr_layer_shell_v1</allow>
<allow>zwlr_virtual_pointer_manager_v1</allow>
</privilegedInterfaces>
```
*<privilegedInterfaces><allow>*
Name of the interface that should be allowed.
This is the full list of interfaces that can be controlled with this mechanism:
- `wp_drm_lease_device_v1`
- `zwlr_gamma_control_manager_v1`
- `zwlr_output_manager_v1`
- `zwlr_output_power_manager_v1`
- `zwp_input_method_manager_v2`
- `zwlr_virtual_pointer_manager_v1`
- `zwp_virtual_keyboard_manager_v1`
- `zwlr_export_dmabuf_manager_v1`
- `zwlr_screencopy_manager_v1`
- `ext_data_control_manager_v1`
- `zwlr_data_control_manager_v1`
- `wp_security_context_manager_v1`
- `ext_idle_notifier_v1`
- `zwlr_foreign_toplevel_manager_v1`
- `ext_foreign_toplevel_list_v1`
- `ext_session_lock_manager_v1`
- `zwlr_layer_shell_v1`
- `ext_workspace_manager_v1`
- `ext_image_copy_capture_manager_v1`
- `ext_output_image_capture_source_manager_v1`
## ENVIRONMENT VARIABLES
*XCURSOR_PATH*

View file

@ -23,6 +23,7 @@ struct keybind {
struct wl_list actions; /* struct action.link */
struct wl_list link; /* struct rcxml.keybinds */
bool on_release;
bool override_inhibition;
};
/**

View file

@ -76,6 +76,7 @@ struct rcxml {
enum tearing_mode allow_tearing;
bool auto_enable_outputs;
bool reuse_output_mode;
uint32_t allowed_interfaces;
bool xwayland_persistence;
bool primary_selection;
char *prompt_command;
@ -225,4 +226,6 @@ void rcxml_finish(void);
*/
void append_parsed_actions(xmlNode *node, struct wl_list *list);
uint32_t parse_privileged_interface(const char *name);
#endif /* LABWC_RCXML_H */

View file

@ -5,12 +5,17 @@
#include <stdbool.h>
#include <stdint.h>
struct seat;
/*
* All keycodes in these functions are (Linux) libinput evdev scancodes which is
* what 'wlr_keyboard' uses (e.g. 'seat->keyboard_group->keyboard->keycodes').
* Note: These keycodes are different to XKB scancodes by a value of 8.
*/
void key_state_indicator_update(struct seat *seat);
void key_state_indicator_toggle(void);
/**
* key_state_pressed_sent_keycodes - generate array of pressed+sent keys
* Note: The array is generated by subtracting any bound keys from _all_ pressed

8
include/show-desktop.h Normal file
View file

@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_SHOW_DESKTOP_H
#define LABWC_SHOW_DESKTOP_H
void show_desktop_toggle(void);
void show_desktop_reset(void);
#endif /* LABWC_SHOW_DESKTOP_H */

View file

@ -184,6 +184,7 @@ struct view {
enum ssd_preference ssd_preference;
bool shaded;
bool minimized;
bool was_minimized_by_show_desktop_action;
enum view_axis maximized;
bool fullscreen;
bool tearing_hint;

View file

@ -1 +1 @@
ar ca cs da de el es et eu fa fi fr gl he hr hu id it ja ka kk ko lt ms nl pa pl pt pt_BR ru sk sv tr uk vi zh_CN zh_TW
ar ca cs da de el es et eu fa fi fr gl he hr hu id it ja ka kab kk ko lt ms nl pa pl pt pt_BR ru sk sv tr uk vi zh_CN zh_TW

80
po/kab.po Normal file
View file

@ -0,0 +1,80 @@
# Labwc pot file
# Copyright (C) 2024
# This file is distributed under the same license as the labwc package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2026-03-31 08:01+0000\n"
"Last-Translator: ButterflyOfFire <butterflyoffire@protonmail.com>\n"
"Language-Team: Kabyle <https://translate.lxqt-project.org/projects/labwc/"
"labwc/kab/>\n"
"Language: kab\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.2.1\n"
#: src/menu/menu.c:1016
msgid "Go there..."
msgstr ""
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "Ixf"
#: src/menu/menu.c:1040
msgid "Reconfigure"
msgstr ""
#: src/menu/menu.c:1042
msgid "Exit"
msgstr "Ffeɣ"
#: src/menu/menu.c:1056
msgid "Minimize"
msgstr ""
#: src/menu/menu.c:1058
msgid "Maximize"
msgstr ""
#: src/menu/menu.c:1060
msgid "Fullscreen"
msgstr "Agdil aččuran"
#: src/menu/menu.c:1062
msgid "Roll Up/Down"
msgstr ""
#: src/menu/menu.c:1064
msgid "Decorations"
msgstr ""
#: src/menu/menu.c:1066
msgid "Always on Top"
msgstr ""
#: src/menu/menu.c:1071
msgid "Move Left"
msgstr ""
#: src/menu/menu.c:1078
msgid "Move Right"
msgstr ""
#: src/menu/menu.c:1083
msgid "Always on Visible Workspace"
msgstr ""
#: src/menu/menu.c:1086
msgid "Workspace"
msgstr ""
#: src/menu/menu.c:1089
msgid "Close"
msgstr "Mdel"

View file

@ -21,12 +21,14 @@
#include "cycle.h"
#include "debug.h"
#include "input/keyboard.h"
#include "input/key-state.h"
#include "labwc.h"
#include "magnifier.h"
#include "menu/menu.h"
#include "output.h"
#include "output-virtual.h"
#include "regions.h"
#include "show-desktop.h"
#include "ssd.h"
#include "theme.h"
#include "translate.h"
@ -132,8 +134,10 @@ struct action_arg_list {
X(TOGGLE_MAGNIFY, "ToggleMagnify") \
X(ZOOM_IN, "ZoomIn") \
X(ZOOM_OUT, "ZoomOut") \
X(TOGGLE_SHOW_DESKTOP, "ToggleShowDesktop") \
X(WARP_CURSOR, "WarpCursor") \
X(HIDE_CURSOR, "HideCursor")
X(HIDE_CURSOR, "HideCursor") \
X(DEBUG_TOGGLE_KEY_STATE_INDICATOR, "DebugToggleKeyStateIndicator")
/*
* Will expand to:
@ -1560,6 +1564,9 @@ run_action(struct view *view, struct action *action,
case ACTION_TYPE_ZOOM_OUT:
magnifier_set_scale(MAGNIFY_DECREASE);
break;
case ACTION_TYPE_TOGGLE_SHOW_DESKTOP:
show_desktop_toggle();
break;
case ACTION_TYPE_WARP_CURSOR: {
const char *to = action_get_str(action, "to", "output");
const char *x = action_get_str(action, "x", "center");
@ -1570,6 +1577,9 @@ run_action(struct view *view, struct action *action,
case ACTION_TYPE_HIDE_CURSOR:
cursor_set_visible(&server.seat, false);
break;
case ACTION_TYPE_DEBUG_TOGGLE_KEY_STATE_INDICATOR:
key_state_indicator_toggle();
break;
case ACTION_TYPE_INVALID:
wlr_log(WLR_ERROR, "Not executing unknown action");
break;

View file

@ -94,6 +94,43 @@ parse_window_type(const char *type)
}
}
uint32_t
parse_privileged_interface(const char *name)
{
static const char * const ifaces[] = {
"wp_drm_lease_device_v1",
"zwlr_gamma_control_manager_v1",
"zwlr_output_manager_v1",
"zwlr_output_power_manager_v1",
"zwp_input_method_manager_v2",
"zwlr_virtual_pointer_manager_v1",
"zwp_virtual_keyboard_manager_v1",
"zwlr_export_dmabuf_manager_v1",
"zwlr_screencopy_manager_v1",
"ext_data_control_manager_v1",
"zwlr_data_control_manager_v1",
"wp_security_context_manager_v1",
"ext_idle_notifier_v1",
"zwlr_foreign_toplevel_manager_v1",
"ext_foreign_toplevel_list_v1",
"ext_session_lock_manager_v1",
"zwlr_layer_shell_v1",
"ext_workspace_manager_v1",
"ext_image_copy_capture_manager_v1",
"ext_output_image_capture_source_manager_v1",
};
static_assert(ARRAY_SIZE(ifaces) <= 32,
"return type too small for amount of privileged protocols");
for (size_t i = 0; i < ARRAY_SIZE(ifaces); i++) {
if (!strcmp(name, ifaces[i])) {
return 1 << i;
}
}
return 0;
}
/*
* Openbox/labwc comparison
*
@ -565,6 +602,7 @@ fill_keybind(xmlNode *node)
lab_xml_get_bool(node, "onRelease", &keybind->on_release);
lab_xml_get_bool(node, "layoutDependent", &keybind->use_syms_only);
lab_xml_get_bool(node, "allowWhenLocked", &keybind->allow_when_locked);
lab_xml_get_bool(node, "overrideInhibition", &keybind->override_inhibition);
append_parsed_actions(node, &keybind->actions);
}
@ -1377,6 +1415,16 @@ entry(xmlNode *node, char *nodename, char *content)
rc.mag_increment = MAX(0, rc.mag_increment);
} else if (!strcasecmp(nodename, "useFilter.magnifier")) {
set_bool(content, &rc.mag_filter);
} else if (!strcasecmp(nodename, "privilegedInterfaces")) {
rc.allowed_interfaces = 0;
} else if (!strcasecmp(nodename, "allow.privilegedInterfaces")) {
uint32_t iface_id = parse_privileged_interface(content);
if (iface_id) {
rc.allowed_interfaces |= iface_id;
} else {
wlr_log(WLR_ERROR, "invalid value for "
"<privilegedInterfaces><allow>");
}
}
return false;
@ -1459,6 +1507,7 @@ rcxml_init(void)
rc.allow_tearing = LAB_TEARING_DISABLED;
rc.auto_enable_outputs = true;
rc.reuse_output_mode = false;
rc.allowed_interfaces = UINT32_MAX;
rc.xwayland_persistence = false;
rc.primary_selection = true;
@ -1658,6 +1707,8 @@ deduplicate_key_bindings(void)
wl_list_remove(&current->link);
keybind_destroy(current);
cleared++;
} else if (actions_contain_toggle_keybinds(&current->actions)) {
current->override_inhibition = true;
}
}
if (replaced) {

View file

@ -2,6 +2,7 @@
#include <assert.h>
#include <wlr/render/allocator.h>
#include <wlr/render/swapchain.h>
#include <wlr/types/wlr_buffer.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_scene.h>
#include "config/rcxml.h"
@ -46,8 +47,12 @@ render_node(struct wlr_render_pass *pass,
if (!scene_buffer->buffer) {
break;
}
struct wlr_texture *texture = wlr_texture_from_buffer(
server.renderer, scene_buffer->buffer);
struct wlr_texture *texture = NULL;
struct wlr_client_buffer *client_buffer =
wlr_client_buffer_get(scene_buffer->buffer);
if (client_buffer) {
texture = client_buffer->texture;
}
if (!texture) {
break;
}
@ -62,7 +67,6 @@ render_node(struct wlr_render_pass *pass,
},
.transform = scene_buffer->transform,
});
wlr_texture_destroy(texture);
break;
}
case WLR_SCENE_NODE_RECT:

View file

@ -14,6 +14,7 @@
#include "layers.h"
#include "node.h"
#include "output.h"
#include "show-desktop.h"
#include "ssd.h"
#include "view.h"
#include "workspaces.h"
@ -113,6 +114,8 @@ desktop_focus_view(struct view *view, bool raise)
*/
struct view *dialog = view_get_modal_dialog(view);
set_or_offer_focus(dialog ? dialog : view);
show_desktop_reset();
}
/* TODO: focus layer-shell surfaces also? */

View file

@ -4,10 +4,171 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_scene.h>
#include <xkbcommon/xkbcommon.h>
#include "config/rcxml.h"
#include "common/buf.h"
#include "common/set.h"
#include "input/keyboard.h"
#include "labwc.h"
#include "scaled-buffer/scaled-font-buffer.h"
static struct lab_set pressed, bound, pressed_sent;
static bool show_debug_indicator;
static struct indicator_state {
struct wlr_scene_tree *tree;
struct scaled_font_buffer *sfb_pressed;
struct scaled_font_buffer *sfb_bound;
struct scaled_font_buffer *sfb_pressed_sent;
struct scaled_font_buffer *sfb_modifiers;
struct xkb_keymap *keymap;
} indicator_state;
static const char *
keycode_to_keyname(struct xkb_keymap *keymap, uint32_t keycode)
{
const xkb_keysym_t *syms;
int syms_len = xkb_keymap_key_get_syms_by_level(keymap, keycode + 8, 0, 0, &syms);
if (!syms_len) {
return NULL;
}
static char buf[256];
if (!xkb_keysym_get_name(syms[0], buf, sizeof(buf))) {
return NULL;
}
return buf;
}
static const char *
modifier_to_name(uint32_t modifier)
{
switch (modifier) {
case WLR_MODIFIER_SHIFT:
return "S";
case WLR_MODIFIER_CAPS:
return "caps";
case WLR_MODIFIER_CTRL:
return "C";
case WLR_MODIFIER_ALT:
return "A";
case WLR_MODIFIER_MOD2:
return "numlock";
case WLR_MODIFIER_MOD3:
return "H";
case WLR_MODIFIER_LOGO:
return "W";
case WLR_MODIFIER_MOD5:
return "M";
default:
return "?";
}
}
static void
init_indicator(struct indicator_state *state)
{
state->tree = wlr_scene_tree_create(&server.scene->tree);
wlr_scene_node_set_enabled(&state->tree->node, false);
state->sfb_pressed = scaled_font_buffer_create(state->tree);
wlr_scene_node_set_position(&state->sfb_pressed->scene_buffer->node, 0, 0);
state->sfb_bound = scaled_font_buffer_create(state->tree);
wlr_scene_node_set_position(&state->sfb_bound->scene_buffer->node, 0, 20);
state->sfb_pressed_sent = scaled_font_buffer_create(state->tree);
wlr_scene_node_set_position(&state->sfb_pressed_sent->scene_buffer->node, 0, 40);
state->sfb_modifiers = scaled_font_buffer_create(state->tree);
wlr_scene_node_set_position(&state->sfb_modifiers->scene_buffer->node, 0, 60);
struct xkb_rule_names rules = { 0 };
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
state->keymap = xkb_map_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
}
static void
update_key_indicator_callback(void *data)
{
struct seat *seat = data;
uint32_t all_modifiers = keyboard_get_all_modifiers(seat);
float black[4] = {0, 0, 0, 1};
float white[4] = {1, 1, 1, 1};
if (!indicator_state.tree) {
init_indicator(&indicator_state);
}
if (show_debug_indicator) {
wlr_scene_node_set_enabled(&indicator_state.tree->node, true);
} else {
wlr_scene_node_set_enabled(&indicator_state.tree->node, false);
return;
}
struct buf buf = BUF_INIT;
buf_add(&buf, "pressed=");
for (int i = 0; i < pressed.size; i++) {
const char *keyname = keycode_to_keyname(indicator_state.keymap,
pressed.values[i]);
buf_add_fmt(&buf, "%s (%d), ", keyname, pressed.values[i]);
}
scaled_font_buffer_update(indicator_state.sfb_pressed, buf.data,
-1, &rc.font_osd, black, white);
buf_clear(&buf);
buf_add(&buf, "bound=");
for (int i = 0; i < bound.size; i++) {
const char *keyname = keycode_to_keyname(indicator_state.keymap,
bound.values[i]);
buf_add_fmt(&buf, "%s (%d), ", keyname, bound.values[i]);
}
scaled_font_buffer_update(indicator_state.sfb_bound, buf.data,
-1, &rc.font_osd, black, white);
buf_clear(&buf);
buf_add(&buf, "pressed_sent=");
for (int i = 0; i < pressed_sent.size; i++) {
const char *keyname = keycode_to_keyname(indicator_state.keymap,
pressed_sent.values[i]);
buf_add_fmt(&buf, "%s (%d), ", keyname, pressed_sent.values[i]);
}
scaled_font_buffer_update(indicator_state.sfb_pressed_sent, buf.data, -1,
&rc.font_osd, black, white);
buf_clear(&buf);
buf_add(&buf, "modifiers=");
for (int i = 0; i <= 7; i++) {
uint32_t mod = 1 << i;
if (all_modifiers & mod) {
buf_add_fmt(&buf, "%s, ", modifier_to_name(mod));
}
}
buf_add_fmt(&buf, "(%d)", all_modifiers);
scaled_font_buffer_update(indicator_state.sfb_modifiers, buf.data, -1,
&rc.font_osd, black, white);
buf_reset(&buf);
}
void
key_state_indicator_update(struct seat *seat)
{
if (!show_debug_indicator) {
return;
}
wl_event_loop_add_idle(server.wl_event_loop,
update_key_indicator_callback, seat);
}
void
key_state_indicator_toggle(void)
{
show_debug_indicator = !show_debug_indicator;
}
static void
report(struct lab_set *key_set, const char *msg)
{

View file

@ -139,6 +139,8 @@ handle_modifiers(struct wl_listener *listener, void *data)
struct seat *seat = keyboard->base.seat;
struct wlr_keyboard *wlr_keyboard = keyboard->wlr_keyboard;
key_state_indicator_update(seat);
if (server.input_mode == LAB_INPUT_STATE_MOVE) {
/* Any change to the modifier state re-enable region snap */
seat->region_prevent_snap = false;
@ -201,8 +203,10 @@ match_keybinding_for_sym(uint32_t modifiers,
if (modifiers ^ keybind->modifiers) {
continue;
}
if (view_inhibits_actions(server.active_view, &keybind->actions)) {
continue;
if (!(keybind->override_inhibition)) {
if (view_inhibits_actions(server.active_view, &keybind->actions)) {
continue;
}
}
if (sym == XKB_KEY_NoSymbol) {
/* Use keycodes */
@ -631,6 +635,9 @@ handle_key(struct wl_listener *listener, void *data)
struct seat *seat = keyboard->base.seat;
struct wlr_keyboard_key_event *event = data;
struct wlr_seat *wlr_seat = seat->wlr_seat;
key_state_indicator_update(seat);
idle_manager_notify_activity(seat->wlr_seat);
/* any new press/release cancels current keybind repeat */

View file

@ -22,6 +22,7 @@ labwc_sources = files(
'seat.c',
'server.c',
'session-lock.c',
'show-desktop.c',
'snap-constraints.c',
'snap.c',
'tearing.c',

View file

@ -9,6 +9,8 @@
#include <wlr/config.h>
#include <wlr/render/allocator.h>
#include <wlr/types/wlr_alpha_modifier_v1.h>
#include <wlr/types/wlr_color_management_v1.h>
#include <wlr/types/wlr_color_representation_v1.h>
#include <wlr/types/wlr_data_control_v1.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_drm.h>
@ -210,39 +212,6 @@ handle_drm_lease_request(struct wl_listener *listener, void *data)
}
#endif
static bool
protocol_is_privileged(const struct wl_interface *iface)
{
static const char * const rejected[] = {
"wp_drm_lease_device_v1",
"zwlr_gamma_control_manager_v1",
"zwlr_output_manager_v1",
"zwlr_output_power_manager_v1",
"zwp_input_method_manager_v2",
"zwlr_virtual_pointer_manager_v1",
"zwp_virtual_keyboard_manager_v1",
"zwlr_export_dmabuf_manager_v1",
"zwlr_screencopy_manager_v1",
"ext_data_control_manager_v1",
"zwlr_data_control_manager_v1",
"wp_security_context_manager_v1",
"ext_idle_notifier_v1",
"zwlr_foreign_toplevel_manager_v1",
"ext_foreign_toplevel_list_v1",
"ext_session_lock_manager_v1",
"zwlr_layer_shell_v1",
"ext_workspace_manager_v1",
"ext_image_copy_capture_manager_v1",
"ext_output_image_capture_source_manager_v1",
};
for (size_t i = 0; i < ARRAY_SIZE(rejected); i++) {
if (!strcmp(iface->name, rejected[i])) {
return true;
}
}
return false;
}
static bool
allow_for_sandbox(const struct wlr_security_context_v1_state *security_state,
const struct wl_interface *iface)
@ -285,6 +254,8 @@ allow_for_sandbox(const struct wlr_security_context_v1_state *security_state,
"xdg_wm_dialog_v1",
/* plus */
"wp_alpha_modifier_v1",
"wp_color_manager_v1",
"wp_color_representation_manager_v1",
"wp_linux_drm_syncobj_manager_v1",
"zxdg_exporter_v1",
"zxdg_exporter_v2",
@ -323,6 +294,11 @@ server_global_filter(const struct wl_client *client, const struct wl_global *glo
}
#endif
uint32_t iface_id = parse_privileged_interface(iface->name);
if (iface_id && !(iface_id & rc.allowed_interfaces)) {
return false;
}
/* Do not allow security_context_manager_v1 to clients with a security context attached */
const struct wlr_security_context_v1_state *security_context =
wlr_security_context_manager_v1_lookup_client(
@ -338,11 +314,11 @@ server_global_filter(const struct wl_client *client, const struct wl_global *glo
/*
* TODO: The following call is basically useless right now
* and should be replaced with
* assert(allow || protocol_is_privileged(iface));
* assert(allow || iface_id);
* This ensures that our lists are in sync with what
* protocols labwc supports.
*/
if (!allow && !protocol_is_privileged(iface)) {
if (!allow && !iface_id) {
wlr_log(WLR_ERROR, "Blocking unknown protocol %s", iface->name);
} else if (!allow) {
wlr_log(WLR_DEBUG, "Blocking %s for security context %s->%s->%s",
@ -592,6 +568,47 @@ server_init(void)
* | output->layer_tree[0] | background layer surfaces (e.g. swaybg)
*/
if (server.renderer->features.input_color_transform) {
const enum wp_color_manager_v1_render_intent render_intents[] = {
WP_COLOR_MANAGER_V1_RENDER_INTENT_PERCEPTUAL,
};
size_t transfer_functions_len = 0;
enum wp_color_manager_v1_transfer_function *transfer_functions =
wlr_color_manager_v1_transfer_function_list_from_renderer(
server.renderer, &transfer_functions_len);
size_t primaries_len = 0;
enum wp_color_manager_v1_primaries *primaries =
wlr_color_manager_v1_primaries_list_from_renderer(
server.renderer, &primaries_len);
struct wlr_color_manager_v1 *cm = wlr_color_manager_v1_create(
server.wl_display, 2, &(struct wlr_color_manager_v1_options){
.features = {
.parametric = true,
.set_mastering_display_primaries = true,
},
.render_intents = render_intents,
.render_intents_len = ARRAY_SIZE(render_intents),
.transfer_functions = transfer_functions,
.transfer_functions_len = transfer_functions_len,
.primaries = primaries,
.primaries_len = primaries_len,
});
free(transfer_functions);
free(primaries);
if (cm) {
wlr_scene_set_color_manager_v1(server.scene, cm);
} else {
wlr_log(WLR_ERROR, "unable to create color manager");
}
}
wlr_color_representation_manager_v1_create_with_renderer(
server.wl_display, 1, server.renderer);
server.workspace_tree = lab_wlr_scene_tree_create(&server.scene->tree);
server.xdg_popup_tree = lab_wlr_scene_tree_create(&server.scene->tree);
#if HAVE_XWAYLAND

78
src/show-desktop.c Normal file
View file

@ -0,0 +1,78 @@
// SPDX-License-Identifier: GPL-2.0-only
#include "show-desktop.h"
#include <wlr/types/wlr_seat.h>
#include "common/array.h"
#include "config/types.h"
#include "labwc.h"
#include "view.h"
static bool is_showing_desktop;
static void
minimize_views(struct wl_array *views, bool minimize)
{
struct view **view;
wl_array_for_each_reverse(view, views) {
view_minimize(*view, minimize);
}
}
static void
show(void)
{
static struct wl_array views;
wl_array_init(&views);
/* Build array first as minimize changes server.views */
struct view *view;
for_each_view(view, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) {
if (view->minimized) {
continue;
}
view->was_minimized_by_show_desktop_action = true;
array_add(&views, view);
}
minimize_views(&views, true);
is_showing_desktop = true;
wl_array_release(&views);
}
static void
restore(void)
{
static struct wl_array views;
wl_array_init(&views);
struct view *view;
for_each_view(view, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) {
if (view->was_minimized_by_show_desktop_action) {
array_add(&views, view);
}
}
minimize_views(&views, false);
show_desktop_reset();
wl_array_release(&views);
}
void
show_desktop_toggle(void)
{
if (is_showing_desktop) {
restore();
} else {
show();
}
}
void
show_desktop_reset(void)
{
is_showing_desktop = false;
struct view *view;
for_each_view(view, &server.views, LAB_VIEW_CRITERIA_NONE) {
view->was_minimized_by_show_desktop_action = false;
}
}

View file

@ -21,6 +21,7 @@
#include "input/keyboard.h"
#include "labwc.h"
#include "output.h"
#include "show-desktop.h"
#include "theme.h"
#include "view.h"
@ -495,6 +496,8 @@ workspaces_switch_to(struct workspace *target, bool update_focus)
desktop_update_top_layer_visibility();
wlr_ext_workspace_handle_v1_set_active(target->ext_workspace, true);
show_desktop_reset();
}
void