mirror of
https://github.com/labwc/labwc.git
synced 2026-04-01 07:15:52 -04:00
SnapToRegion: Add config parser
This commit is contained in:
parent
51727cf8f7
commit
43fe138385
5 changed files with 86 additions and 0 deletions
|
|
@ -59,6 +59,9 @@ struct rcxml {
|
||||||
int popuptime;
|
int popuptime;
|
||||||
struct wl_list workspaces; /* struct workspace.link */
|
struct wl_list workspaces; /* struct workspace.link */
|
||||||
} workspace_config;
|
} workspace_config;
|
||||||
|
|
||||||
|
/* Regions */
|
||||||
|
struct wl_list regions; /* struct region.link */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct rcxml rc;
|
extern struct rcxml rc;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@ struct region {
|
||||||
} center;
|
} center;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Can be used as a cheap check to detect if there are any regions configured */
|
||||||
|
bool regions_available(void);
|
||||||
|
|
||||||
void regions_init(struct server *server, struct seat *seat);
|
void regions_init(struct server *server, struct seat *seat);
|
||||||
void regions_update(struct output *output);
|
void regions_update(struct output *output);
|
||||||
void regions_destroy(struct wl_list *regions);
|
void regions_destroy(struct wl_list *regions);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
#include <wlr/util/box.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "action.h"
|
#include "action.h"
|
||||||
#include "common/list.h"
|
#include "common/list.h"
|
||||||
|
|
@ -22,8 +23,10 @@
|
||||||
#include "config/libinput.h"
|
#include "config/libinput.h"
|
||||||
#include "config/mousebind.h"
|
#include "config/mousebind.h"
|
||||||
#include "config/rcxml.h"
|
#include "config/rcxml.h"
|
||||||
|
#include "regions.h"
|
||||||
#include "workspaces.h"
|
#include "workspaces.h"
|
||||||
|
|
||||||
|
static bool in_regions;
|
||||||
static bool in_keybind;
|
static bool in_keybind;
|
||||||
static bool in_mousebind;
|
static bool in_mousebind;
|
||||||
static bool in_libinput_category;
|
static bool in_libinput_category;
|
||||||
|
|
@ -33,6 +36,7 @@ static struct libinput_category *current_libinput_category;
|
||||||
static const char *current_mouse_context;
|
static const char *current_mouse_context;
|
||||||
static struct action *current_keybind_action;
|
static struct action *current_keybind_action;
|
||||||
static struct action *current_mousebind_action;
|
static struct action *current_mousebind_action;
|
||||||
|
static struct region *current_region;
|
||||||
|
|
||||||
enum font_place {
|
enum font_place {
|
||||||
FONT_PLACE_NONE = 0,
|
FONT_PLACE_NONE = 0,
|
||||||
|
|
@ -46,6 +50,44 @@ enum font_place {
|
||||||
static void load_default_key_bindings(void);
|
static void load_default_key_bindings(void);
|
||||||
static void load_default_mouse_bindings(void);
|
static void load_default_mouse_bindings(void);
|
||||||
|
|
||||||
|
static void
|
||||||
|
fill_region(char *nodename, char *content)
|
||||||
|
{
|
||||||
|
string_truncate_at_pattern(nodename, ".region.regions");
|
||||||
|
|
||||||
|
if (!strcasecmp(nodename, "region.regions")) {
|
||||||
|
current_region = znew(*current_region);
|
||||||
|
wl_list_append(&rc.regions, ¤t_region->link);
|
||||||
|
} else if (!content) {
|
||||||
|
/* intentionally left empty */
|
||||||
|
} else if (!current_region) {
|
||||||
|
wlr_log(WLR_ERROR, "Expecting <region name=\"\" before %s='%s'",
|
||||||
|
nodename, content);
|
||||||
|
} else if (!strcasecmp(nodename, "name")) {
|
||||||
|
/* Prevent leaking memory if config contains multiple names */
|
||||||
|
if (!current_region->name) {
|
||||||
|
current_region->name = xstrdup(content);
|
||||||
|
}
|
||||||
|
} else if (strstr("xywidtheight", nodename) && !strchr(content, '%')) {
|
||||||
|
wlr_log(WLR_ERROR, "Removing invalid region '%s': %s='%s' misses"
|
||||||
|
" a trailing %%", current_region->name, nodename, content);
|
||||||
|
wl_list_remove(¤t_region->link);
|
||||||
|
zfree(current_region->name);
|
||||||
|
zfree(current_region);
|
||||||
|
} else if (!strcmp(nodename, "x")) {
|
||||||
|
current_region->percentage.x = atoi(content);
|
||||||
|
} else if (!strcmp(nodename, "y")) {
|
||||||
|
current_region->percentage.y = atoi(content);
|
||||||
|
} else if (!strcmp(nodename, "width")) {
|
||||||
|
current_region->percentage.width = atoi(content);
|
||||||
|
} else if (!strcmp(nodename, "height")) {
|
||||||
|
current_region->percentage.height = atoi(content);
|
||||||
|
} else {
|
||||||
|
wlr_log(WLR_ERROR, "Unexpected data in region parser: %s=\"%s\"",
|
||||||
|
nodename, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fill_keybind(char *nodename, char *content)
|
fill_keybind(char *nodename, char *content)
|
||||||
{
|
{
|
||||||
|
|
@ -321,6 +363,10 @@ entry(xmlNode *node, char *nodename, char *content)
|
||||||
if (in_libinput_category) {
|
if (in_libinput_category) {
|
||||||
fill_libinput_category(nodename, content);
|
fill_libinput_category(nodename, content);
|
||||||
}
|
}
|
||||||
|
if (in_regions) {
|
||||||
|
fill_region(nodename, content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* handle nodes without content, e.g. <keyboard><default /> */
|
/* handle nodes without content, e.g. <keyboard><default /> */
|
||||||
if (!strcmp(nodename, "default.keyboard")) {
|
if (!strcmp(nodename, "default.keyboard")) {
|
||||||
|
|
@ -457,6 +503,12 @@ xml_tree_walk(xmlNode *node)
|
||||||
in_libinput_category = false;
|
in_libinput_category = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcasecmp((char *)n->name, "regions")) {
|
||||||
|
in_regions = true;
|
||||||
|
traverse(n);
|
||||||
|
in_regions = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
traverse(n);
|
traverse(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -502,6 +554,7 @@ rcxml_init()
|
||||||
rc.cycle_preview_outlines = true;
|
rc.cycle_preview_outlines = true;
|
||||||
rc.workspace_config.popuptime = INT_MIN;
|
rc.workspace_config.popuptime = INT_MIN;
|
||||||
wl_list_init(&rc.workspace_config.workspaces);
|
wl_list_init(&rc.workspace_config.workspaces);
|
||||||
|
wl_list_init(&rc.regions);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
|
|
@ -693,6 +746,23 @@ post_processing(void)
|
||||||
if (rc.workspace_config.popuptime == INT_MIN) {
|
if (rc.workspace_config.popuptime == INT_MIN) {
|
||||||
rc.workspace_config.popuptime = 1000;
|
rc.workspace_config.popuptime = 1000;
|
||||||
}
|
}
|
||||||
|
struct region *region, *region_tmp;
|
||||||
|
wl_list_for_each_safe(region, region_tmp, &rc.regions, link) {
|
||||||
|
struct wlr_box box = region->percentage;
|
||||||
|
bool invalid = !region->name
|
||||||
|
|| box.x < 0 || box.x > 100
|
||||||
|
|| box.y < 0 || box.y > 100
|
||||||
|
|| box.width <= 0 || box.width > 100
|
||||||
|
|| box.height <= 0 || box.height > 100;
|
||||||
|
if (invalid) {
|
||||||
|
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);
|
||||||
|
zfree(region->name);
|
||||||
|
free(region);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -798,6 +868,8 @@ rcxml_finish(void)
|
||||||
zfree(w);
|
zfree(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
regions_destroy(&rc.regions);
|
||||||
|
|
||||||
/* Reset state vars for starting fresh when Reload is triggered */
|
/* Reset state vars for starting fresh when Reload is triggered */
|
||||||
current_keybind = NULL;
|
current_keybind = NULL;
|
||||||
current_mousebind = NULL;
|
current_mousebind = NULL;
|
||||||
|
|
@ -805,4 +877,5 @@ rcxml_finish(void)
|
||||||
current_mouse_context = NULL;
|
current_mouse_context = NULL;
|
||||||
current_keybind_action = NULL;
|
current_keybind_action = NULL;
|
||||||
current_mousebind_action = NULL;
|
current_mousebind_action = NULL;
|
||||||
|
current_region = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ labwc_sources = files(
|
||||||
'node.c',
|
'node.c',
|
||||||
'osd.c',
|
'osd.c',
|
||||||
'output.c',
|
'output.c',
|
||||||
|
'regions.c',
|
||||||
'resistance.c',
|
'resistance.c',
|
||||||
'seat.c',
|
'seat.c',
|
||||||
'server.c',
|
'server.c',
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,12 @@
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "regions.h"
|
#include "regions.h"
|
||||||
|
|
||||||
|
bool
|
||||||
|
regions_available(void)
|
||||||
|
{
|
||||||
|
return !wl_list_empty(&rc.regions);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
regions_init(struct server *server, struct seat *seat)
|
regions_init(struct server *server, struct seat *seat)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue