mirror of
https://github.com/labwc/labwc.git
synced 2026-06-13 14:33:18 -04:00
add config dialog
This commit is contained in:
parent
ff2f243eb1
commit
c8889c7fb7
12 changed files with 230 additions and 59 deletions
|
|
@ -50,6 +50,7 @@ enum lab_node_type {
|
|||
LAB_NODE_CYCLE_OSD_ITEM,
|
||||
LAB_NODE_LAYER_SURFACE,
|
||||
LAB_NODE_UNMANAGED,
|
||||
LAB_NODE_CONFIG_DIALOG,
|
||||
LAB_NODE_ALL,
|
||||
|
||||
/* translated to LAB_NODE_CLIENT by get_cursor_context() */
|
||||
|
|
|
|||
23
include/config/dialog.h
Normal file
23
include/config/dialog.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef LAB_DIALOG_H
|
||||
#define LAB_DIALOG_H
|
||||
|
||||
struct wlr_scene_node;
|
||||
|
||||
/**
|
||||
* dialog_create_callback - creates the config dialog,
|
||||
* used with wl_event_loop_add_idle.
|
||||
*
|
||||
* @data: Ignored.
|
||||
*/
|
||||
void dialog_create_callback(void *data);
|
||||
|
||||
/**
|
||||
* dialog_destroy - destroys a dialog that is a child of
|
||||
* server.dialog_tree, destroys all children if NULL is provided.
|
||||
*
|
||||
* @dialog: Dialog to be destroyed
|
||||
*/
|
||||
void dialog_destroy(struct wlr_scene_node *dialog);
|
||||
|
||||
#endif /* LAB_DIALOG_H */
|
||||
|
|
@ -17,6 +17,28 @@
|
|||
/* max of one button of each type (no repeats) */
|
||||
#define TITLE_BUTTONS_MAX ((LAB_NODE_BUTTON_LAST + 1) - LAB_NODE_BUTTON_FIRST)
|
||||
|
||||
struct log_item {
|
||||
char *text;
|
||||
struct wl_list link; /* struct rcxml.error_logs */
|
||||
};
|
||||
|
||||
/**
|
||||
* Calls wlr_log(verb, fmt, ...) and also saves it in
|
||||
* rc.error_logs for displaying it in a dialog later.
|
||||
* Only sets rc.has_error when WLR_ERROR is used to log
|
||||
* other relevant info like the config file.
|
||||
*/
|
||||
#define lab_wlr_log(verb, fmt, ...) \
|
||||
do { \
|
||||
wlr_log(verb, fmt, ##__VA_ARGS__); \
|
||||
if (verb == WLR_ERROR) { \
|
||||
rc.has_error = true; \
|
||||
} \
|
||||
struct log_item *log_item = znew(*log_item); \
|
||||
log_item->text = strdup_printf(fmt, ##__VA_ARGS__); \
|
||||
wl_list_append(&rc.error_logs, &log_item->link); \
|
||||
} while (0)
|
||||
|
||||
enum adaptive_sync_mode {
|
||||
LAB_ADAPTIVE_SYNC_DISABLED,
|
||||
LAB_ADAPTIVE_SYNC_ENABLED,
|
||||
|
|
@ -213,6 +235,10 @@ struct rcxml {
|
|||
float mag_scale;
|
||||
float mag_increment;
|
||||
bool mag_filter;
|
||||
|
||||
/* Error log */
|
||||
bool has_error;
|
||||
struct wl_list error_logs; /* struct log_item.link */
|
||||
};
|
||||
|
||||
/* defined in main.c */
|
||||
|
|
|
|||
|
|
@ -230,6 +230,9 @@ struct server {
|
|||
/* Tree for all non-layer xdg/xwayland-shell surfaces */
|
||||
struct wlr_scene_tree *workspace_tree;
|
||||
|
||||
/* Tree for error dialog */
|
||||
struct wlr_scene_tree *dialog_tree;
|
||||
|
||||
/*
|
||||
* Popups need to be rendered above always-on-top views, so we reparent
|
||||
* them to this dedicated tree
|
||||
|
|
|
|||
24
src/action.c
24
src/action.c
|
|
@ -318,7 +318,7 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
|
|||
|| action->type == ACTION_TYPE_SNAP_TO_EDGE);
|
||||
enum lab_edge edge = lab_edge_parse(content, tiled, /*any*/ false);
|
||||
if (edge == LAB_EDGE_NONE) {
|
||||
wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
lab_wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
action_names[action->type], argument, content);
|
||||
} else {
|
||||
action_arg_add_int(action, argument, edge);
|
||||
|
|
@ -347,7 +347,7 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
|
|||
} else if (!strcasecmp(content, "current")) {
|
||||
action_arg_add_int(action, argument, CYCLE_WORKSPACE_CURRENT);
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
lab_wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
action_names[action->type], argument, content);
|
||||
}
|
||||
goto cleanup;
|
||||
|
|
@ -360,7 +360,7 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
|
|||
} else if (!strcasecmp(content, "focused")) {
|
||||
action_arg_add_int(action, argument, CYCLE_OUTPUT_FOCUSED);
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
lab_wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
action_names[action->type], argument, content);
|
||||
}
|
||||
goto cleanup;
|
||||
|
|
@ -371,7 +371,7 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
|
|||
} else if (!strcasecmp(content, "current")) {
|
||||
action_arg_add_int(action, argument, CYCLE_APP_ID_CURRENT);
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
lab_wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
action_names[action->type], argument, content);
|
||||
}
|
||||
goto cleanup;
|
||||
|
|
@ -401,7 +401,7 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
|
|||
if (!strcmp(argument, "direction")) {
|
||||
enum view_axis axis = view_axis_parse(content);
|
||||
if (axis == VIEW_AXIS_NONE || axis == VIEW_AXIS_INVALID) {
|
||||
wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
lab_wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
action_names[action->type], argument, content);
|
||||
} else {
|
||||
action_arg_add_int(action, argument, axis);
|
||||
|
|
@ -415,7 +415,7 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
|
|||
if (mode != LAB_SSD_MODE_INVALID) {
|
||||
action_arg_add_int(action, argument, mode);
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
lab_wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
action_names[action->type], argument, content);
|
||||
}
|
||||
goto cleanup;
|
||||
|
|
@ -430,7 +430,7 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
|
|||
enum lab_edge edge = lab_edge_parse(content,
|
||||
/*tiled*/ true, /*any*/ false);
|
||||
if (edge == LAB_EDGE_NONE || edge == LAB_EDGE_CENTER) {
|
||||
wlr_log(WLR_ERROR,
|
||||
lab_wlr_log(WLR_ERROR,
|
||||
"Invalid argument for action %s: '%s' (%s)",
|
||||
action_names[action->type], argument, content);
|
||||
} else {
|
||||
|
|
@ -497,7 +497,7 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
|
|||
enum lab_edge edge = lab_edge_parse(content,
|
||||
/*tiled*/ false, /*any*/ false);
|
||||
if (edge == LAB_EDGE_NONE) {
|
||||
wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
lab_wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
action_names[action->type], argument, content);
|
||||
} else {
|
||||
action_arg_add_int(action, argument, edge);
|
||||
|
|
@ -521,7 +521,7 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
|
|||
enum lab_placement_policy policy =
|
||||
view_placement_parse(content);
|
||||
if (policy == LAB_PLACE_INVALID) {
|
||||
wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
lab_wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
|
||||
action_names[action->type], argument, content);
|
||||
} else {
|
||||
action_arg_add_int(action, argument, policy);
|
||||
|
|
@ -542,7 +542,7 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s'",
|
||||
lab_wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s'",
|
||||
action_names[action->type], argument);
|
||||
|
||||
cleanup:
|
||||
|
|
@ -557,7 +557,7 @@ action_type_from_str(const char *action_name)
|
|||
return i;
|
||||
}
|
||||
}
|
||||
wlr_log(WLR_ERROR, "Invalid action: %s", action_name);
|
||||
lab_wlr_log(WLR_ERROR, "Invalid action: %s", action_name);
|
||||
return ACTION_TYPE_INVALID;
|
||||
}
|
||||
|
||||
|
|
@ -664,7 +664,7 @@ action_is_valid(struct action *action)
|
|||
return true;
|
||||
}
|
||||
|
||||
wlr_log(WLR_ERROR, "Missing required argument for %s: %s",
|
||||
lab_wlr_log(WLR_ERROR, "Missing required argument for %s: %s",
|
||||
action_names[action->type], arg_name);
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
88
src/config/dialog.c
Normal file
88
src/config/dialog.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "config/dialog.h"
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/util/box.h>
|
||||
#include "common/lab-scene-rect.h"
|
||||
#include "common/scene-helpers.h"
|
||||
#include "config/rcxml.h"
|
||||
#include "labwc.h"
|
||||
#include "node.h"
|
||||
#include "output.h"
|
||||
#include "scaled-buffer/scaled-font-buffer.h"
|
||||
#include "theme.h"
|
||||
|
||||
static void
|
||||
dialog_create(void)
|
||||
{
|
||||
struct theme *theme = rc.theme;
|
||||
float *text_color = theme->osd_label_text_color;
|
||||
float *bg_color = theme->osd_bg_color;
|
||||
|
||||
struct output *output = output_nearest_to_cursor();
|
||||
struct wlr_box output_box = output_usable_area_in_layout_coords(output);
|
||||
|
||||
int border = theme->osd_border_width;
|
||||
int padding = rc.font_osd.size / 2; /* used for padding and line gap */
|
||||
int x = output_box.x + output_box.width / 4;
|
||||
int y = output_box.y + output_box.height / 10;
|
||||
int width = output_box.width * 0.5;
|
||||
int height = output_box.height * 0.8;
|
||||
int inner_w = width - 2 * border;
|
||||
int inner_h = height - 2 * border;
|
||||
int dx = border + padding;
|
||||
int dy = border + padding;
|
||||
struct wlr_scene_tree *dialog = lab_wlr_scene_tree_create(server.dialog_tree);
|
||||
node_descriptor_create(&dialog->node, LAB_NODE_CONFIG_DIALOG, NULL, NULL);
|
||||
|
||||
wlr_scene_node_set_position(&dialog->node, x, y);
|
||||
struct wlr_scene_rect *border_rect = lab_wlr_scene_rect_create(dialog, width, height,
|
||||
theme->osd_border_color);
|
||||
wlr_scene_node_set_position(&border_rect->node, 0, 0);
|
||||
struct wlr_scene_tree *dialog_tree = lab_wlr_scene_tree_create(dialog);
|
||||
wlr_scene_node_set_position(&dialog_tree->node, border, border);
|
||||
struct wlr_scene_rect *dialog_rect = lab_wlr_scene_rect_create(dialog_tree,
|
||||
inner_w, inner_h, bg_color);
|
||||
wlr_scene_node_set_position(&dialog_rect->node, 0, 0);
|
||||
|
||||
struct scaled_font_buffer *font_buf = scaled_font_buffer_create(dialog_tree);
|
||||
struct font title_font = rc.font_osd;
|
||||
title_font.size *= 1.15;
|
||||
scaled_font_buffer_update(font_buf, "Config log (Click to dismiss)", inner_w,
|
||||
&title_font, text_color, bg_color);
|
||||
wlr_scene_node_set_position(&font_buf->scene_buffer->node, dx, dy);
|
||||
dy += font_buf->height + padding;
|
||||
|
||||
struct log_item *item;
|
||||
wl_list_for_each(item, &rc.error_logs, link) {
|
||||
font_buf = scaled_font_buffer_create(dialog_tree);
|
||||
scaled_font_buffer_update(font_buf, item->text, inner_w, &rc.font_osd,
|
||||
text_color, bg_color);
|
||||
wlr_scene_node_set_position(&font_buf->scene_buffer->node, dx, dy);
|
||||
dy += font_buf->height + padding;
|
||||
}
|
||||
wlr_scene_node_set_enabled(&server.dialog_tree->node, true);
|
||||
}
|
||||
|
||||
void
|
||||
dialog_create_callback(void *data)
|
||||
{
|
||||
dialog_create();
|
||||
}
|
||||
|
||||
void
|
||||
dialog_destroy(struct wlr_scene_node *dialog)
|
||||
{
|
||||
struct wlr_scene_node *child, *tmp;
|
||||
wl_list_for_each_safe(child, tmp, &server.dialog_tree->children, link) {
|
||||
if (!dialog) {
|
||||
wlr_scene_node_destroy(child);
|
||||
continue;
|
||||
}
|
||||
if (dialog == child) {
|
||||
wlr_scene_node_destroy(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
labwc_sources += files(
|
||||
'dialog.c',
|
||||
'rcxml.c',
|
||||
'keybind.c',
|
||||
'session.c',
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "common/string-helpers.h"
|
||||
#include "common/xml.h"
|
||||
#include "config/default-bindings.h"
|
||||
#include "config/dialog.h"
|
||||
#include "config/keybind.h"
|
||||
#include "config/libinput.h"
|
||||
#include "config/mousebind.h"
|
||||
|
|
@ -168,7 +169,7 @@ fill_section(const char *content, enum lab_node_type *buttons, int *count,
|
|||
#if HAVE_LIBSFDO
|
||||
type = LAB_NODE_BUTTON_WINDOW_ICON;
|
||||
#else
|
||||
wlr_log(WLR_ERROR, "libsfdo is not linked. "
|
||||
lab_wlr_log(WLR_ERROR, "libsfdo is not linked. "
|
||||
"Replacing 'icon' in titlebar layout with 'menu'.");
|
||||
type = LAB_NODE_BUTTON_WINDOW_MENU;
|
||||
#endif
|
||||
|
|
@ -185,7 +186,7 @@ fill_section(const char *content, enum lab_node_type *buttons, int *count,
|
|||
} else if (!strcmp(identifier, "desk")) {
|
||||
type = LAB_NODE_BUTTON_OMNIPRESENT;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "invalid titleLayout identifier '%s'",
|
||||
lab_wlr_log(WLR_ERROR, "invalid titleLayout identifier '%s'",
|
||||
identifier);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -194,7 +195,7 @@ fill_section(const char *content, enum lab_node_type *buttons, int *count,
|
|||
|
||||
/* We no longer need this check, but let's keep it just in case */
|
||||
if (*found_buttons & (1 << type)) {
|
||||
wlr_log(WLR_ERROR, "ignoring duplicated button type '%s'",
|
||||
lab_wlr_log(WLR_ERROR, "ignoring duplicated button type '%s'",
|
||||
identifier);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -223,7 +224,7 @@ fill_title_layout(const char *content)
|
|||
gchar **parts = g_strsplit(content, ":", -1);
|
||||
|
||||
if (g_strv_length(parts) != 2) {
|
||||
wlr_log(WLR_ERROR, "<titlebar><layout> must contain one colon");
|
||||
lab_wlr_log(WLR_ERROR, "<titlebar><layout> must contain one colon");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
|
@ -259,7 +260,7 @@ fill_usable_area_override(xmlNode *node)
|
|||
} else if (!strcmp(key, "bottom")) {
|
||||
usable_area_override->margin.bottom = atoi(content);
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Unexpected data usable-area-override "
|
||||
lab_wlr_log(WLR_ERROR, "Unexpected data usable-area-override "
|
||||
"parser: %s=\"%s\"", key, content);
|
||||
}
|
||||
}
|
||||
|
|
@ -324,7 +325,7 @@ fill_window_rule(xmlNode *node)
|
|||
} else if (!strcasecmp(content, "server")) {
|
||||
window_rule->icon_prefer_client = LAB_PROP_FALSE;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR,
|
||||
lab_wlr_log(WLR_ERROR,
|
||||
"Invalid value for window rule property 'iconPriority'");
|
||||
}
|
||||
} else if (!strcasecmp(key, "skipTaskbar")) {
|
||||
|
|
@ -409,7 +410,7 @@ fill_region(xmlNode *node)
|
|||
xstrdup_replace(region->name, content);
|
||||
} else if (strstr("xywidtheight", key)
|
||||
&& !strchr(content, '%')) {
|
||||
wlr_log(WLR_ERROR, "Removing invalid region "
|
||||
lab_wlr_log(WLR_ERROR, "Removing invalid region "
|
||||
"'%s': %s='%s' misses a trailing %%",
|
||||
region->name, key, content);
|
||||
wl_list_remove(®ion->link);
|
||||
|
|
@ -425,7 +426,7 @@ fill_region(xmlNode *node)
|
|||
} else if (!strcmp(key, "height")) {
|
||||
region->percentage.height = atoi(content);
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Unexpected data in region "
|
||||
lab_wlr_log(WLR_ERROR, "Unexpected data in region "
|
||||
"parser: %s=\"%s\"", key, content);
|
||||
}
|
||||
}
|
||||
|
|
@ -592,7 +593,7 @@ fill_keybind(xmlNode *node)
|
|||
if (lab_xml_get_string(node, "key", keyname, sizeof(keyname))) {
|
||||
keybind = keybind_create(keyname);
|
||||
if (!keybind) {
|
||||
wlr_log(WLR_ERROR, "Invalid keybind: %s", keyname);
|
||||
lab_wlr_log(WLR_ERROR, "Invalid keybind: %s", keyname);
|
||||
}
|
||||
}
|
||||
if (!keybind) {
|
||||
|
|
@ -672,7 +673,7 @@ fill_touch(xmlNode *node)
|
|||
} else if (!strcasecmp(key, "mouseEmulation")) {
|
||||
set_bool(content, &touch_config->force_mouse_emulation);
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Unexpected data in touch parser: %s=\"%s\"",
|
||||
lab_wlr_log(WLR_ERROR, "Unexpected data in touch parser: %s=\"%s\"",
|
||||
key, content);
|
||||
}
|
||||
}
|
||||
|
|
@ -688,14 +689,14 @@ fill_tablet_button_map(xmlNode *node)
|
|||
if (lab_xml_get_string(node, "button", buf, sizeof(buf))) {
|
||||
map_from = tablet_button_from_str(buf);
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Invalid 'button' argument for tablet button mapping");
|
||||
lab_wlr_log(WLR_ERROR, "Invalid 'button' argument for tablet button mapping");
|
||||
return;
|
||||
}
|
||||
|
||||
if (lab_xml_get_string(node, "to", buf, sizeof(buf))) {
|
||||
map_to = mousebind_button_from_str(buf, NULL);
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Invalid 'to' argument for tablet button mapping");
|
||||
lab_wlr_log(WLR_ERROR, "Invalid 'to' argument for tablet button mapping");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -754,7 +755,7 @@ fill_libinput_category(xmlNode *node)
|
|||
char *key, *content;
|
||||
LAB_XML_FOR_EACH(node, child, key, content) {
|
||||
if (string_null_or_empty(content)) {
|
||||
wlr_log(WLR_ERROR, "Empty string is not allowed for "
|
||||
lab_wlr_log(WLR_ERROR, "Empty string is not allowed for "
|
||||
"<libinput><device><%s>. Ignoring.", key);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -801,7 +802,7 @@ fill_libinput_category(xmlNode *node)
|
|||
category->tap_button_map =
|
||||
LIBINPUT_CONFIG_TAP_MAP_LMR;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "invalid tapButtonMap");
|
||||
lab_wlr_log(WLR_ERROR, "invalid tapButtonMap");
|
||||
}
|
||||
} else if (!strcasecmp(key, "tapAndDrag")) {
|
||||
int ret = parse_bool(content, -1);
|
||||
|
|
@ -846,7 +847,7 @@ fill_libinput_category(xmlNode *node)
|
|||
: LIBINPUT_CONFIG_3FG_DRAG_DISABLED;
|
||||
}
|
||||
#else
|
||||
wlr_log(WLR_ERROR, "<threeFingerDrag> is only"
|
||||
lab_wlr_log(WLR_ERROR, "<threeFingerDrag> is only"
|
||||
" supported in libinput >= 1.28");
|
||||
#endif
|
||||
} else if (!strcasecmp(key, "accelProfile")) {
|
||||
|
|
@ -879,7 +880,7 @@ fill_libinput_category(xmlNode *node)
|
|||
category->click_method =
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "invalid clickMethod");
|
||||
lab_wlr_log(WLR_ERROR, "invalid clickMethod");
|
||||
}
|
||||
} else if (!strcasecmp(key, "scrollMethod")) {
|
||||
if (!strcasecmp(content, "none")) {
|
||||
|
|
@ -895,14 +896,14 @@ fill_libinput_category(xmlNode *node)
|
|||
category->scroll_method =
|
||||
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "invalid scrollMethod");
|
||||
lab_wlr_log(WLR_ERROR, "invalid scrollMethod");
|
||||
}
|
||||
} else if (!strcasecmp(key, "scrollButton")) {
|
||||
int button = atoi(content);
|
||||
if (button != 0) {
|
||||
category->scroll_button = button;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "invalid scrollButton");
|
||||
lab_wlr_log(WLR_ERROR, "invalid scrollButton");
|
||||
}
|
||||
} else if (!strcasecmp(key, "sendEventsMode")) {
|
||||
category->send_events_mode =
|
||||
|
|
@ -918,7 +919,7 @@ fill_libinput_category(xmlNode *node)
|
|||
mat[i] = strtof(elements[i], &end_str);
|
||||
if (errno == ERANGE || *end_str != '\0' || i == 6
|
||||
|| *elements[i] == '\0') {
|
||||
wlr_log(WLR_ERROR, "invalid calibration "
|
||||
lab_wlr_log(WLR_ERROR, "invalid calibration "
|
||||
"matrix element %s (index %d), "
|
||||
"expect six floats", elements[i], i);
|
||||
category->have_calibration_matrix = false;
|
||||
|
|
@ -927,7 +928,7 @@ fill_libinput_category(xmlNode *node)
|
|||
}
|
||||
}
|
||||
if (i != 6 && category->have_calibration_matrix) {
|
||||
wlr_log(WLR_ERROR, "wrong number of calibration "
|
||||
lab_wlr_log(WLR_ERROR, "wrong number of calibration "
|
||||
"matrix elements, expected 6, got %d", i);
|
||||
category->have_calibration_matrix = false;
|
||||
}
|
||||
|
|
@ -1128,7 +1129,7 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
return true;
|
||||
|
||||
} else if (str_space_only(content)) {
|
||||
wlr_log(WLR_ERROR, "Empty string is not allowed for %s. "
|
||||
lab_wlr_log(WLR_ERROR, "Empty string is not allowed for %s. "
|
||||
"Ignoring.", nodename);
|
||||
|
||||
/* handle non-empty leaf nodes */
|
||||
|
|
@ -1203,7 +1204,7 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
if (doubleclick_time_parsed > 0) {
|
||||
rc.doubleclick_time = doubleclick_time_parsed;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "invalid doubleClickTime");
|
||||
lab_wlr_log(WLR_ERROR, "invalid doubleClickTime");
|
||||
}
|
||||
} else if (!strcasecmp(nodename, "scrollFactor.mouse")) {
|
||||
/* This is deprecated. Show an error message in post_processing() */
|
||||
|
|
@ -1235,7 +1236,7 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
} else if (!strcasecmp(nodename, "range.snapping")) {
|
||||
rc.snap_edge_range_inner = atoi(content);
|
||||
rc.snap_edge_range_outer = atoi(content);
|
||||
wlr_log(WLR_ERROR, "<snapping><range> is deprecated. "
|
||||
lab_wlr_log(WLR_ERROR, "<snapping><range> is deprecated. "
|
||||
"Use <snapping><range inner=\"\" outer=\"\"> instead.");
|
||||
} else if (!strcasecmp(nodename, "inner.range.snapping")) {
|
||||
rc.snap_edge_range_inner = atoi(content);
|
||||
|
|
@ -1261,7 +1262,7 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
} else if (!strcasecmp(content, "never")) {
|
||||
rc.snap_tiling_events_mode = LAB_TILING_EVENTS_NEVER;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "ignoring invalid value for notifyClient");
|
||||
lab_wlr_log(WLR_ERROR, "ignoring invalid value for notifyClient");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1279,7 +1280,7 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
} else if (!strcasecmp(content, "thumbnail")) {
|
||||
rc.window_switcher.osd.style = CYCLE_OSD_STYLE_THUMBNAIL;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Invalid windowSwitcher style '%s': "
|
||||
lab_wlr_log(WLR_ERROR, "Invalid windowSwitcher style '%s': "
|
||||
"should be one of classic|thumbnail", content);
|
||||
}
|
||||
} else if (!strcasecmp(nodename, "output.osd.windowSwitcher")) {
|
||||
|
|
@ -1290,7 +1291,7 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
} else if (!strcasecmp(content, "focused")) {
|
||||
rc.window_switcher.osd.output_filter = CYCLE_OUTPUT_FOCUSED;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Invalid windowSwitcher output '%s': "
|
||||
lab_wlr_log(WLR_ERROR, "Invalid windowSwitcher output '%s': "
|
||||
"should be one of all|focused|cursor", content);
|
||||
}
|
||||
} else if (!strcasecmp(nodename, "order.windowSwitcher")) {
|
||||
|
|
@ -1299,14 +1300,14 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
} else if (!strcasecmp(content, "age")) {
|
||||
rc.window_switcher.order = WINDOW_SWITCHER_ORDER_AGE;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Invalid windowSwitcher order '%s': "
|
||||
lab_wlr_log(WLR_ERROR, "Invalid windowSwitcher order '%s': "
|
||||
"should be one of focus|age", content);
|
||||
}
|
||||
|
||||
/* The following two are for backward compatibility only. */
|
||||
} else if (!strcasecmp(nodename, "show.windowSwitcher")) {
|
||||
set_bool(content, &rc.window_switcher.osd.show);
|
||||
wlr_log(WLR_ERROR, "<windowSwitcher show=\"\" /> is deprecated."
|
||||
lab_wlr_log(WLR_ERROR, "<windowSwitcher show=\"\" /> is deprecated."
|
||||
" Use <windowSwitcher><osd show=\"\" />");
|
||||
} else if (!strcasecmp(nodename, "style.windowSwitcher")) {
|
||||
if (!strcasecmp(content, "classic")) {
|
||||
|
|
@ -1314,7 +1315,7 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
} else if (!strcasecmp(content, "thumbnail")) {
|
||||
rc.window_switcher.osd.style = CYCLE_OSD_STYLE_THUMBNAIL;
|
||||
}
|
||||
wlr_log(WLR_ERROR, "<windowSwitcher style=\"\" /> is deprecated."
|
||||
lab_wlr_log(WLR_ERROR, "<windowSwitcher style=\"\" /> is deprecated."
|
||||
" Use <windowSwitcher><osd style=\"\" />");
|
||||
|
||||
} else if (!strcasecmp(nodename, "preview.windowSwitcher")) {
|
||||
|
|
@ -1324,20 +1325,20 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
} else if (!strcasecmp(nodename, "allWorkspaces.windowSwitcher")) {
|
||||
int ret = parse_bool(content, -1);
|
||||
if (ret < 0) {
|
||||
wlr_log(WLR_ERROR, "Invalid value for <windowSwitcher"
|
||||
lab_wlr_log(WLR_ERROR, "Invalid value for <windowSwitcher"
|
||||
" allWorkspaces=\"\">: '%s'", content);
|
||||
} else {
|
||||
rc.window_switcher.workspace_filter = ret ?
|
||||
CYCLE_WORKSPACE_ALL : CYCLE_WORKSPACE_CURRENT;
|
||||
}
|
||||
wlr_log(WLR_ERROR, "<windowSwitcher allWorkspaces=\"\" /> is deprecated."
|
||||
lab_wlr_log(WLR_ERROR, "<windowSwitcher allWorkspaces=\"\" /> is deprecated."
|
||||
" Use <action name=\"NextWindow\" workspace=\"\"> instead.");
|
||||
} else if (!strcasecmp(nodename, "unshade.windowSwitcher")) {
|
||||
set_bool(content, &rc.window_switcher.unshade);
|
||||
|
||||
/* Remove this long term - just a friendly warning for now */
|
||||
} else if (strstr(nodename, "windowswitcher.core")) {
|
||||
wlr_log(WLR_ERROR, "<windowSwitcher> should not be child of <core>");
|
||||
lab_wlr_log(WLR_ERROR, "<windowSwitcher> should not be child of <core>");
|
||||
|
||||
/* The following three are for backward compatibility only */
|
||||
} else if (!strcasecmp(nodename, "show.windowSwitcher.core")) {
|
||||
|
|
@ -1350,15 +1351,15 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
/* The following three are for backward compatibility only */
|
||||
} else if (!strcasecmp(nodename, "cycleViewOSD.core")) {
|
||||
set_bool(content, &rc.window_switcher.osd.show);
|
||||
wlr_log(WLR_ERROR, "<cycleViewOSD> is deprecated."
|
||||
lab_wlr_log(WLR_ERROR, "<cycleViewOSD> is deprecated."
|
||||
" Use <windowSwitcher show=\"\" />");
|
||||
} else if (!strcasecmp(nodename, "cycleViewPreview.core")) {
|
||||
set_bool(content, &rc.window_switcher.preview);
|
||||
wlr_log(WLR_ERROR, "<cycleViewPreview> is deprecated."
|
||||
lab_wlr_log(WLR_ERROR, "<cycleViewPreview> is deprecated."
|
||||
" Use <windowSwitcher preview=\"\" />");
|
||||
} else if (!strcasecmp(nodename, "cycleViewOutlines.core")) {
|
||||
set_bool(content, &rc.window_switcher.outlines);
|
||||
wlr_log(WLR_ERROR, "<cycleViewOutlines> is deprecated."
|
||||
lab_wlr_log(WLR_ERROR, "<cycleViewOutlines> is deprecated."
|
||||
" Use <windowSwitcher outlines=\"\" />");
|
||||
|
||||
} else if (!strcasecmp(nodename, "name.names.desktops")) {
|
||||
|
|
@ -1379,7 +1380,7 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
} else if (!strcasecmp(content, "Nonpixel")) {
|
||||
rc.resize_indicator = LAB_RESIZE_INDICATOR_NON_PIXEL;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Invalid value for <resize popupShow />");
|
||||
lab_wlr_log(WLR_ERROR, "Invalid value for <resize popupShow />");
|
||||
}
|
||||
} else if (!strcasecmp(nodename, "drawContents.resize")) {
|
||||
set_bool(content, &rc.resize_draw_contents);
|
||||
|
|
@ -1435,7 +1436,7 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
if (iface_id) {
|
||||
rc.allowed_interfaces |= iface_id;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "invalid value for "
|
||||
lab_wlr_log(WLR_ERROR, "invalid value for "
|
||||
"<privilegedInterfaces><allow>");
|
||||
}
|
||||
}
|
||||
|
|
@ -1464,7 +1465,7 @@ rcxml_parse_xml(struct buf *b)
|
|||
int options = 0;
|
||||
xmlDoc *d = xmlReadMemory(b->data, b->len, NULL, NULL, options);
|
||||
if (!d) {
|
||||
wlr_log(WLR_ERROR, "error parsing config file");
|
||||
lab_wlr_log(WLR_ERROR, "error parsing config file");
|
||||
return;
|
||||
}
|
||||
xmlNode *root = xmlDocGetRootElement(d);
|
||||
|
|
@ -1495,6 +1496,7 @@ rcxml_init(void)
|
|||
wl_list_init(&rc.mousebinds);
|
||||
wl_list_init(&rc.libinput_categories);
|
||||
wl_list_init(&rc.workspace_config.workspaces);
|
||||
wl_list_init(&rc.error_logs);
|
||||
wl_list_init(&rc.regions);
|
||||
wl_list_init(&rc.window_switcher.osd.fields);
|
||||
wl_list_init(&rc.window_rules);
|
||||
|
|
@ -1843,7 +1845,7 @@ post_processing(void)
|
|||
assert(l && libinput_category_get_default() == l);
|
||||
}
|
||||
if (mouse_scroll_factor >= 0) {
|
||||
wlr_log(WLR_ERROR, "<mouse><scrollFactor> is deprecated"
|
||||
lab_wlr_log(WLR_ERROR, "<mouse><scrollFactor> is deprecated"
|
||||
" and overwrites <libinput><scrollFactor>."
|
||||
" Use only <libinput><scrollFactor>.");
|
||||
struct libinput_category *l;
|
||||
|
|
@ -1903,7 +1905,7 @@ validate_actions(void)
|
|||
if (!action_is_valid(action)) {
|
||||
wl_list_remove(&action->link);
|
||||
action_free(action);
|
||||
wlr_log(WLR_ERROR, "Removed invalid keybind action");
|
||||
lab_wlr_log(WLR_ERROR, "Removed invalid keybind action");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1914,7 +1916,7 @@ validate_actions(void)
|
|||
if (!action_is_valid(action)) {
|
||||
wl_list_remove(&action->link);
|
||||
action_free(action);
|
||||
wlr_log(WLR_ERROR, "Removed invalid mousebind action");
|
||||
lab_wlr_log(WLR_ERROR, "Removed invalid mousebind action");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1925,7 +1927,7 @@ validate_actions(void)
|
|||
if (!action_is_valid(action)) {
|
||||
wl_list_remove(&action->link);
|
||||
action_free(action);
|
||||
wlr_log(WLR_ERROR, "Removed invalid window rule action");
|
||||
lab_wlr_log(WLR_ERROR, "Removed invalid window rule action");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1944,7 +1946,7 @@ validate(void)
|
|||
|| box.width <= 0 || box.width > 100
|
||||
|| box.height <= 0 || box.height > 100;
|
||||
if (invalid) {
|
||||
wlr_log(WLR_ERROR,
|
||||
lab_wlr_log(WLR_ERROR,
|
||||
"Removing invalid region '%s': %d%% x %d%% @ %d%%,%d%%",
|
||||
region->name, box.width, box.height, box.x, box.y);
|
||||
wl_list_remove(®ion->link);
|
||||
|
|
@ -1958,7 +1960,7 @@ validate(void)
|
|||
wl_list_for_each_safe(rule, rule_tmp, &rc.window_rules, link) {
|
||||
if (!rule->identifier && !rule->title && rule->window_type < 0
|
||||
&& !rule->sandbox_engine && !rule->sandbox_app_id) {
|
||||
wlr_log(WLR_ERROR, "Deleting rule %p as it has no criteria", rule);
|
||||
lab_wlr_log(WLR_ERROR, "Deleting rule %p as it has no criteria", rule);
|
||||
rule_destroy(rule);
|
||||
}
|
||||
}
|
||||
|
|
@ -1971,7 +1973,7 @@ validate(void)
|
|||
wl_list_for_each_safe(field, field_tmp, &rc.window_switcher.osd.fields, link) {
|
||||
field_width_sum += field->width;
|
||||
if (!cycle_osd_field_is_valid(field) || field_width_sum > 100) {
|
||||
wlr_log(WLR_ERROR, "Deleting invalid window switcher field %p", field);
|
||||
lab_wlr_log(WLR_ERROR, "Deleting invalid window switcher field %p", field);
|
||||
wl_list_remove(&field->link);
|
||||
cycle_osd_field_free(field);
|
||||
}
|
||||
|
|
@ -2017,7 +2019,7 @@ rcxml_read(const char *filename)
|
|||
continue;
|
||||
}
|
||||
|
||||
wlr_log(WLR_INFO, "read config file %s", path->string);
|
||||
lab_wlr_log(WLR_INFO, "read config file %s", path->string);
|
||||
|
||||
rcxml_parse_xml(&b);
|
||||
buf_reset(&b);
|
||||
|
|
@ -2092,6 +2094,15 @@ rcxml_finish(void)
|
|||
zfree(w);
|
||||
}
|
||||
|
||||
struct log_item *log_item, *log_tmp;
|
||||
wl_list_for_each_safe(log_item, log_tmp, &rc.error_logs, link) {
|
||||
wl_list_remove(&log_item->link);
|
||||
zfree(log_item->text);
|
||||
zfree(log_item);
|
||||
}
|
||||
rc.has_error = false;
|
||||
dialog_destroy(NULL);
|
||||
|
||||
regions_destroy(NULL, &rc.regions);
|
||||
|
||||
clear_window_switcher_fields();
|
||||
|
|
|
|||
|
|
@ -426,6 +426,10 @@ get_cursor_context(void)
|
|||
ret.type = desc->type;
|
||||
}
|
||||
|
||||
return ret;
|
||||
case LAB_NODE_CONFIG_DIALOG:
|
||||
ret.type = LAB_NODE_CONFIG_DIALOG;
|
||||
ret.node = node;
|
||||
return ret;
|
||||
default:
|
||||
/* Other node types are not attached a scene node */
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/util/region.h>
|
||||
#include "action.h"
|
||||
#include "config/dialog.h"
|
||||
#include "common/macros.h"
|
||||
#include "common/mem.h"
|
||||
#include "config/mousebind.h"
|
||||
|
|
@ -1236,7 +1237,10 @@ cursor_process_button_release(struct seat *seat, uint32_t button,
|
|||
}
|
||||
return notify;
|
||||
}
|
||||
|
||||
if (ctx.type == LAB_NODE_CONFIG_DIALOG) {
|
||||
dialog_destroy(ctx.node);
|
||||
return notify;
|
||||
}
|
||||
if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) {
|
||||
return notify;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "common/fd-util.h"
|
||||
#include "common/font.h"
|
||||
#include "common/spawn.h"
|
||||
#include "config/dialog.h"
|
||||
#include "config/rcxml.h"
|
||||
#include "config/session.h"
|
||||
#include "labwc.h"
|
||||
|
|
@ -263,6 +264,10 @@ main(int argc, char *argv[])
|
|||
|
||||
menu_init();
|
||||
|
||||
if (rc.has_error) {
|
||||
wl_event_loop_add_idle(server.wl_event_loop, dialog_create_callback, NULL);
|
||||
}
|
||||
|
||||
/* Delay startup of applications until the event loop is ready */
|
||||
struct idle_ctx idle_ctx = {
|
||||
.primary_client = primary_client,
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include "common/macros.h"
|
||||
#include "common/mem.h"
|
||||
#include "common/scene-helpers.h"
|
||||
#include "config/dialog.h"
|
||||
#include "config/rcxml.h"
|
||||
#include "config/session.h"
|
||||
#include "decorations.h"
|
||||
|
|
@ -118,6 +119,9 @@ reload_config_and_theme(void)
|
|||
resize_indicator_reconfigure();
|
||||
kde_server_decoration_update_default();
|
||||
workspaces_reconfigure();
|
||||
if (rc.has_error) {
|
||||
wl_event_loop_add_idle(server.wl_event_loop, dialog_create_callback, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -616,6 +620,7 @@ server_init(void)
|
|||
server.wl_display, 1, server.renderer);
|
||||
|
||||
server.workspace_tree = lab_wlr_scene_tree_create(&server.scene->tree);
|
||||
server.dialog_tree = lab_wlr_scene_tree_create(&server.scene->tree);
|
||||
server.xdg_popup_tree = lab_wlr_scene_tree_create(&server.scene->tree);
|
||||
#if HAVE_XWAYLAND
|
||||
// Creating/setting this is harmless when xwayland support is built-in
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue