Margins support

This commit is contained in:
Keith Bowes 2022-02-25 20:20:10 -05:00
parent e9bf441ed0
commit 23287f482d
4 changed files with 39 additions and 17 deletions

View file

@ -1,5 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<openbox_config xmlns="http://openbox.org/3.4/rc" xmlns:xi="http://www.w3.org/2001/XInclude"> <openbox_config xmlns="http://openbox.org/3.4/rc" xmlns:xi="http://www.w3.org/2001/XInclude">
<margins>
<top>0</top>
<bottom>0</bottom>
<left>0</left>
<right>0</right>
</margins>
<keyboard> <keyboard>
<!-- Keyboard layout. See `man xkeyboard-config` for more information --> <!-- Keyboard layout. See `man xkeyboard-config` for more information -->
<!-- You can use the XKB_* environment variables instead --> <!-- You can use the XKB_* environment variables instead -->

View file

@ -21,17 +21,18 @@ static char *parse_xpath_expr(char *expr, xmlXPathContextPtr ctxt) {
return (char *) ret; return (char *) ret;
} }
static xmlChar *get_attribute(xmlNode *node, char *attr_name) {
xmlAttr *attr = node->properties;
while (attr && strcmp((char *) attr->name, attr_name) != 0)
attr = attr->next;
return attr->children->content;
}
static void get_action(xmlNode *new_node, struct wb_key_binding *key_bind) { static void get_action(xmlNode *new_node, struct wb_key_binding *key_bind) {
xmlAttr *attr;
xmlNode *cur_node; xmlNode *cur_node;
for (cur_node = new_node; cur_node; cur_node = cur_node->next) { for (cur_node = new_node; cur_node; cur_node = cur_node->next) {
if (strcmp((char *) cur_node->name, "action") == 0) { if (strcmp((char *) cur_node->name, "action") == 0) {
attr = cur_node->properties; char *action = (char *) get_attribute(cur_node, "name");
if (!attr) continue;
while (strcmp((char *) attr->name, "name") != 0) {
attr = attr->next;
}
char *action = (char *) attr->children->content;
if (strcmp(action, "Execute") == 0) if (strcmp(action, "Execute") == 0)
key_bind->action |= ACTION_EXECUTE; key_bind->action |= ACTION_EXECUTE;
else if (strcmp(action, "NextWindow") == 0) else if (strcmp(action, "NextWindow") == 0)
@ -82,13 +83,10 @@ static bool parse_key_bindings(struct wb_config *config, xmlXPathContextPtr ctxt
for (i = 0; i < object->nodesetval->nodeNr; i++) { for (i = 0; i < object->nodesetval->nodeNr; i++) {
if (object->nodesetval->nodeTab[i]) { if (object->nodesetval->nodeTab[i]) {
/* First get the key combinations */ /* First get the key combinations */
xmlAttr *keycomb = object->nodesetval->nodeTab[i]->properties; xmlNode *keycomb = object->nodesetval->nodeTab[i];
while (strcmp((char *) keycomb->name, "key") != 0)
keycomb = keycomb->next;
char *sym; char *sym;
uint32_t modifiers = 0; uint32_t modifiers = 0;
sym = (char *) keycomb->children->content; sym = (char *) get_attribute(keycomb, "key");
char *s; char *s;
struct wb_key_binding *key_bind = calloc(1, sizeof(struct wb_key_binding)); struct wb_key_binding *key_bind = calloc(1, sizeof(struct wb_key_binding));
@ -129,6 +127,7 @@ static bool parse_key_bindings(struct wb_config *config, xmlXPathContextPtr ctxt
} }
bool init_config(struct wb_server *server) { bool init_config(struct wb_server *server) {
struct wb_config *config = calloc(1, sizeof(struct wb_config));
xmlDocPtr doc; xmlDocPtr doc;
char *rc_file; char *rc_file;
if (getenv("WB_RC_XML")) { if (getenv("WB_RC_XML")) {
@ -162,7 +161,6 @@ bool init_config(struct wb_server *server) {
wlr_log(WLR_INFO, "%s", _("Couldn't register the namespace")); wlr_log(WLR_INFO, "%s", _("Couldn't register the namespace"));
} }
struct wb_config *config = calloc(1, sizeof(struct wb_config));
config->keyboard_layout.use_config = parse_xpath_expr("//ob:keyboard//ob:keyboardLayout", ctxt) != NULL; config->keyboard_layout.use_config = parse_xpath_expr("//ob:keyboard//ob:keyboardLayout", ctxt) != NULL;
if (config->keyboard_layout.use_config) { if (config->keyboard_layout.use_config) {
@ -176,6 +174,12 @@ bool init_config(struct wb_server *server) {
xmlFreeDoc(doc); xmlFreeDoc(doc);
return false; return false;
} }
config->margins.bottom = strtoul(parse_xpath_expr("//ob:margins/ob:bottom", ctxt), NULL, 10);
config->margins.left = strtoul(parse_xpath_expr("//ob:margins/ob:left", ctxt), NULL, 10);
config->margins.right = strtoul(parse_xpath_expr("//ob:margins/ob:right", ctxt), NULL, 10);
config->margins.top = strtoul(parse_xpath_expr("//ob:margins/ob:top", ctxt), NULL, 10);
server->config = config; server->config = config;
xmlXPathFreeContext(ctxt); xmlXPathFreeContext(ctxt);

View file

@ -27,6 +27,12 @@ struct wb_config {
bool use_config; bool use_config;
} keyboard_layout; } keyboard_layout;
struct {
int bottom;
int left;
int right;
int top;
} margins;
struct wl_list applications; struct wl_list applications;
struct wl_list key_bindings; struct wl_list key_bindings;

View file

@ -59,9 +59,9 @@ static void xdg_surface_commit(struct wl_listener *listener, void *data) {
struct wlr_box geo_box = {0}; struct wlr_box geo_box = {0};
wlr_xdg_surface_get_geometry(xdg_surface, &geo_box); wlr_xdg_surface_get_geometry(xdg_surface, &geo_box);
if (geo_box.x < 0 && view->current_position.x < 1) if (geo_box.x < 0 && view->current_position.x - view->server->config->margins.left < 1)
view->current_position.x += -geo_box.x; view->current_position.x += -geo_box.x;
if (geo_box.y < 0 && view->current_position.y < 1) { if (geo_box.y < 0 && view->current_position.y - view->server->config->margins.top < 1) {
view->decoration_height = -geo_box.y; view->decoration_height = -geo_box.y;
view->current_position.y += view->decoration_height; view->current_position.y += view->decoration_height;
} }
@ -74,9 +74,12 @@ static void xdg_surface_map(struct wl_listener *listener, void *data) {
if (view->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) if (view->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
return; return;
struct wb_config *config = view->server->config;
struct wlr_box geo_box = {0}; struct wlr_box geo_box = {0};
wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box); wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box);
view->current_position = geo_box; view->current_position = geo_box;
view->current_position.x = config->margins.left;
view->current_position.y = config->margins.top;
#if WLR_CHECK_VERSION(0, 16, 0) #if WLR_CHECK_VERSION(0, 16, 0)
wlr_xdg_toplevel_set_size(view->xdg_toplevel, geo_box.width, geo_box.height); wlr_xdg_toplevel_set_size(view->xdg_toplevel, geo_box.width, geo_box.height);
#else #else
@ -133,10 +136,13 @@ static void xdg_toplevel_request_maximize(struct wl_listener *listener, void *da
bool is_maximized = surface->toplevel->current.maximized; bool is_maximized = surface->toplevel->current.maximized;
struct wlr_box usable_area = {0}; struct wlr_box usable_area = {0};
if (!is_maximized) { if (!is_maximized) {
struct wb_config *config = view->server->config;
wlr_output_effective_resolution(output, &usable_area.width, &usable_area.height); wlr_output_effective_resolution(output, &usable_area.width, &usable_area.height);
view->previous_position = view->current_position; view->previous_position = view->current_position;
view->current_position.x = 0; view->current_position.x = config->margins.left;
view->current_position.y = 0 + view->decoration_height; view->current_position.y = config->margins.top + view->decoration_height;
usable_area.height -= config->margins.top + config->margins.bottom;
usable_area.width -= config->margins.left + config->margins.right;
} else { } else {
usable_area = view->previous_position; usable_area = view->previous_position;
view->current_position.x = view->previous_position.x; view->current_position.x = view->previous_position.x;