Compare commits
7 Commits
56f211480f
...
fc038eda35
| Author | SHA1 | Date | |
|---|---|---|---|
|
fc038eda35
|
|||
|
c93e78bbd6
|
|||
|
19e97b730b
|
|||
|
2ab4a84236
|
|||
|
e394ed78a5
|
|||
|
46140e1e03
|
|||
|
f3b8be8cf1
|
@@ -111,7 +111,7 @@ typedef struct zdwm_api_t {
|
|||||||
zdwm_binding_mode_id_t bind_mode,
|
zdwm_binding_mode_id_t bind_mode,
|
||||||
const char *key_sequence,
|
const char *key_sequence,
|
||||||
zdwm_action_fn action_fn,
|
zdwm_action_fn action_fn,
|
||||||
zdwm_action_arg_t *action_arg
|
zdwm_action_arg_t action_arg
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <xcb/randr.h>
|
#include <xcb/randr.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xcb_aux.h>
|
#include <xcb/xcb_aux.h>
|
||||||
|
#include <xcb/xcb_keysyms.h>
|
||||||
#include <xcb/xfixes.h>
|
#include <xcb/xfixes.h>
|
||||||
#include <xcb/xinerama.h>
|
#include <xcb/xinerama.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
@@ -160,6 +161,8 @@ backend_t *backend_create(const char *display_name) {
|
|||||||
backend->have_xfixes = false;
|
backend->have_xfixes = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backend->key_symbols = xcb_key_symbols_alloc(conn);
|
||||||
|
|
||||||
atoms_init(backend);
|
atoms_init(backend);
|
||||||
create_wm_check_window(backend);
|
create_wm_check_window(backend);
|
||||||
create_no_focus_window(backend);
|
create_no_focus_window(backend);
|
||||||
@@ -176,9 +179,15 @@ void backend_destroy(backend_t *backend) {
|
|||||||
p_delete(&backend->unmap.windows);
|
p_delete(&backend->unmap.windows);
|
||||||
p_clear(&backend->unmap, 1);
|
p_clear(&backend->unmap, 1);
|
||||||
|
|
||||||
|
p_delete(&backend->map.windows);
|
||||||
|
p_clear(&backend->map, 1);
|
||||||
|
|
||||||
p_delete(&backend->kill.windows);
|
p_delete(&backend->kill.windows);
|
||||||
p_clear(&backend->kill, 1);
|
p_clear(&backend->kill, 1);
|
||||||
|
|
||||||
|
xcb_key_symbols_free(backend->key_symbols);
|
||||||
|
backend->key_symbols = nullptr;
|
||||||
|
|
||||||
xcb_disconnect(backend->conn);
|
xcb_disconnect(backend->conn);
|
||||||
backend->conn = nullptr;
|
backend->conn = nullptr;
|
||||||
free(backend);
|
free(backend);
|
||||||
@@ -456,6 +465,12 @@ find_or_push_configure(window_configure_list_t *configs, xcb_window_t window) {
|
|||||||
return cfg;
|
return cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
backend_bind_key(backend_t *backend, const effect_bind_key_t *bind_key) {
|
||||||
|
auto root = backend->screen->root;
|
||||||
|
window_grab_keys(backend, root, bind_key->keys, bind_key->count);
|
||||||
|
}
|
||||||
|
|
||||||
static void backend_merge_effects(
|
static void backend_merge_effects(
|
||||||
backend_t *backend,
|
backend_t *backend,
|
||||||
const effect_t *effects,
|
const effect_t *effects,
|
||||||
@@ -517,6 +532,9 @@ static void backend_merge_effects(
|
|||||||
backend_restack_windows(backend, &e->as.restack_windows);
|
backend_restack_windows(backend, &e->as.restack_windows);
|
||||||
backend_change_window_list(backend, true, &e->as.restack_windows);
|
backend_change_window_list(backend, true, &e->as.restack_windows);
|
||||||
break;
|
break;
|
||||||
|
case ZDWM_EFFECT_BIND_KEY:
|
||||||
|
backend_bind_key(backend, &e->as.bind_key);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,11 @@
|
|||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xcb_event.h>
|
#include <xcb/xcb_event.h>
|
||||||
#include <xcb/xcb_icccm.h>
|
#include <xcb/xcb_icccm.h>
|
||||||
|
#include <xcb/xcb_keysyms.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
#include "backend/x11/window.h"
|
#include "backend/x11/window.h"
|
||||||
|
#include "base/macros.h"
|
||||||
#include "base/memory.h"
|
#include "base/memory.h"
|
||||||
#include "core/backend.h"
|
#include "core/backend.h"
|
||||||
#include "core/types.h"
|
#include "core/types.h"
|
||||||
@@ -91,7 +93,6 @@ static bool handle_map_request(
|
|||||||
) {
|
) {
|
||||||
xcb_window_t window = xcb_event->window;
|
xcb_window_t window = xcb_event->window;
|
||||||
|
|
||||||
event_reset(event);
|
|
||||||
event->type = ZDWM_EVENT_WINDOW_MAP_REQUEST;
|
event->type = ZDWM_EVENT_WINDOW_MAP_REQUEST;
|
||||||
|
|
||||||
window_map_request_event_t *ev = &event->as.window_map_request;
|
window_map_request_event_t *ev = &event->as.window_map_request;
|
||||||
@@ -170,9 +171,10 @@ static bool handle_unmap_notify(
|
|||||||
event_t *event,
|
event_t *event,
|
||||||
const xcb_unmap_notify_event_t *xcb_event
|
const xcb_unmap_notify_event_t *xcb_event
|
||||||
) {
|
) {
|
||||||
event_reset(event);
|
event->type = ZDWM_EVENT_WINDOW_REMOVE;
|
||||||
event->type = ZDWM_EVENT_WINDOW_REMOVE;
|
event->as.window_remove.window = xcb_event->window;
|
||||||
/* TODO: */
|
event->as.window_remove.reason = ZDWM_WINDOW_REMOVE_WITHDRAWN;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,9 +183,10 @@ static bool handle_destroy_notify(
|
|||||||
event_t *event,
|
event_t *event,
|
||||||
const xcb_destroy_notify_event_t *xcb_event
|
const xcb_destroy_notify_event_t *xcb_event
|
||||||
) {
|
) {
|
||||||
event_reset(event);
|
event->type = ZDWM_EVENT_WINDOW_REMOVE;
|
||||||
event->type = ZDWM_EVENT_WINDOW_REMOVE;
|
event->as.window_remove.window = xcb_event->window;
|
||||||
/* TODO: */
|
event->as.window_remove.reason = ZDWM_WINDOW_REMOVE_DESTROY;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,12 +195,52 @@ static bool handle_configure_request(
|
|||||||
event_t *event,
|
event_t *event,
|
||||||
const xcb_configure_request_event_t *xcb_event
|
const xcb_configure_request_event_t *xcb_event
|
||||||
) {
|
) {
|
||||||
event_reset(event);
|
|
||||||
event->type = ZDWM_EVENT_CONFIGURE_REQUEST;
|
event->type = ZDWM_EVENT_CONFIGURE_REQUEST;
|
||||||
/* TODO: */
|
/* TODO: */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static modifier_mask_t get_modifiers(uint16_t mask) {
|
||||||
|
typedef struct modifier_map_t {
|
||||||
|
modifier_bit_t modifier;
|
||||||
|
xcb_mod_mask_t mask;
|
||||||
|
} modifier_map_t;
|
||||||
|
static constexpr modifier_map_t modifier_map[] = {
|
||||||
|
{ZDWM_MOD_SHIFT, XCB_MOD_MASK_SHIFT},
|
||||||
|
{ZDWM_MOD_CONTROL, XCB_MOD_MASK_CONTROL},
|
||||||
|
{ZDWM_MOD_1, XCB_MOD_MASK_1},
|
||||||
|
{ZDWM_MOD_2, XCB_MOD_MASK_2},
|
||||||
|
{ZDWM_MOD_3, XCB_MOD_MASK_3},
|
||||||
|
{ZDWM_MOD_4, XCB_MOD_MASK_4},
|
||||||
|
{ZDWM_MOD_5, XCB_MOD_MASK_5},
|
||||||
|
};
|
||||||
|
|
||||||
|
auto mods = ZDWM_MOD_NONE;
|
||||||
|
for (size_t i = 0; i < countof(modifier_map); ++i) {
|
||||||
|
auto item = &modifier_map[i];
|
||||||
|
if (mask & item->mask) mods |= item->modifier;
|
||||||
|
}
|
||||||
|
return mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool handle_key_press(
|
||||||
|
backend_t *backend,
|
||||||
|
event_t *event,
|
||||||
|
const xcb_key_press_event_t *xcb_event
|
||||||
|
) {
|
||||||
|
auto keycode = xcb_event->detail;
|
||||||
|
|
||||||
|
/* keysym without any modifiers */
|
||||||
|
auto keysym = xcb_key_symbols_get_keysym(backend->key_symbols, keycode, 0);
|
||||||
|
|
||||||
|
event->type = ZDWM_EVENT_KEY_PRESS;
|
||||||
|
event->as.key_press.keycode = keycode;
|
||||||
|
event->as.key_press.keysym = keysym;
|
||||||
|
event->as.key_press.modifiers = get_modifiers(xcb_event->state);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool backend_next_event(backend_t *backend, event_t *event) {
|
bool backend_next_event(backend_t *backend, event_t *event) {
|
||||||
if (!backend || !backend->conn || !event) return false;
|
if (!backend || !backend->conn || !event) return false;
|
||||||
|
|
||||||
@@ -213,6 +256,7 @@ bool backend_next_event(backend_t *backend, event_t *event) {
|
|||||||
switch (response_type) {
|
switch (response_type) {
|
||||||
#define EVENT(type, handler) \
|
#define EVENT(type, handler) \
|
||||||
case type: \
|
case type: \
|
||||||
|
event_reset(event); \
|
||||||
handled = handler(backend, event, (void *)raw_event); \
|
handled = handler(backend, event, (void *)raw_event); \
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -220,6 +264,7 @@ bool backend_next_event(backend_t *backend, event_t *event) {
|
|||||||
EVENT(XCB_UNMAP_NOTIFY, handle_unmap_notify);
|
EVENT(XCB_UNMAP_NOTIFY, handle_unmap_notify);
|
||||||
EVENT(XCB_DESTROY_NOTIFY, handle_destroy_notify);
|
EVENT(XCB_DESTROY_NOTIFY, handle_destroy_notify);
|
||||||
EVENT(XCB_CONFIGURE_REQUEST, handle_configure_request);
|
EVENT(XCB_CONFIGURE_REQUEST, handle_configure_request);
|
||||||
|
EVENT(XCB_KEY_PRESS, handle_key_press);
|
||||||
|
|
||||||
#undef EVENT
|
#undef EVENT
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xcb_keysyms.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
#define ATOM_LIST(X) \
|
#define ATOM_LIST(X) \
|
||||||
@@ -76,6 +77,7 @@ typedef struct window_list_t {
|
|||||||
} window_list_t;
|
} window_list_t;
|
||||||
|
|
||||||
struct backend_t {
|
struct backend_t {
|
||||||
|
xcb_key_symbols_t *key_symbols;
|
||||||
xcb_connection_t *conn;
|
xcb_connection_t *conn;
|
||||||
xcb_screen_t *screen;
|
xcb_screen_t *screen;
|
||||||
int screenp;
|
int screenp;
|
||||||
|
|||||||
@@ -4,11 +4,14 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xcb_icccm.h>
|
#include <xcb/xcb_icccm.h>
|
||||||
|
#include <xcb/xcb_keysyms.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
#include "base/array.h"
|
#include "base/array.h"
|
||||||
|
#include "base/macros.h"
|
||||||
#include "base/memory.h"
|
#include "base/memory.h"
|
||||||
#include "core/backend.h"
|
#include "core/backend.h"
|
||||||
|
#include "core/types.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
static char *window_get_text_property(
|
static char *window_get_text_property(
|
||||||
@@ -326,3 +329,52 @@ void window_list_reset(window_list_t *window_list) {
|
|||||||
p_clear(window_list->windows, window_list->count);
|
p_clear(window_list->windows, window_list->count);
|
||||||
window_list->count = 0;
|
window_list->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint16_t get_xcb_modifier(modifier_mask_t modifiers) {
|
||||||
|
typedef struct modifier_map_t {
|
||||||
|
modifier_bit_t modifier;
|
||||||
|
xcb_mod_mask_t mask;
|
||||||
|
} modifier_map_t;
|
||||||
|
static constexpr modifier_map_t modifier_map[] = {
|
||||||
|
{ZDWM_MOD_SHIFT, XCB_MOD_MASK_SHIFT},
|
||||||
|
{ZDWM_MOD_CONTROL, XCB_MOD_MASK_CONTROL},
|
||||||
|
{ZDWM_MOD_1, XCB_MOD_MASK_1},
|
||||||
|
{ZDWM_MOD_2, XCB_MOD_MASK_2},
|
||||||
|
{ZDWM_MOD_3, XCB_MOD_MASK_3},
|
||||||
|
{ZDWM_MOD_4, XCB_MOD_MASK_4},
|
||||||
|
{ZDWM_MOD_5, XCB_MOD_MASK_5},
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16_t mods = ZDWM_MOD_NONE;
|
||||||
|
for (size_t i = 0; i < countof(modifier_map); ++i) {
|
||||||
|
auto item = &modifier_map[i];
|
||||||
|
if (modifiers & item->modifier) mods |= item->mask;
|
||||||
|
}
|
||||||
|
return mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
void window_grab_keys(
|
||||||
|
backend_t *backend,
|
||||||
|
xcb_window_t window,
|
||||||
|
const key_bind_t *keys,
|
||||||
|
size_t count
|
||||||
|
) {
|
||||||
|
auto conn = backend->conn;
|
||||||
|
auto key_symbols = backend->key_symbols;
|
||||||
|
|
||||||
|
xcb_ungrab_key(conn, XCB_GRAB_ANY, window, XCB_MOD_MASK_ANY);
|
||||||
|
|
||||||
|
xcb_grab_mode_t mode = XCB_GRAB_MODE_ASYNC;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
auto key = &keys[i];
|
||||||
|
auto keycodes = xcb_key_symbols_get_keycode(key_symbols, keys->keysym);
|
||||||
|
if (!keycodes) continue;
|
||||||
|
|
||||||
|
auto modifiers = get_xcb_modifier(key->modifiers);
|
||||||
|
for (auto keycode = keycodes; *keycode != XCB_NO_SYMBOL; ++keycode) {
|
||||||
|
xcb_grab_key(conn, true, window, modifiers, *keycode, mode, mode);
|
||||||
|
}
|
||||||
|
p_delete(&keycodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -87,3 +87,10 @@ void window_clean_event_mask(xcb_connection_t *conn, xcb_window_t window);
|
|||||||
|
|
||||||
void window_list_push(window_list_t *window_list, xcb_window_t window);
|
void window_list_push(window_list_t *window_list, xcb_window_t window);
|
||||||
void window_list_reset(window_list_t *window_list);
|
void window_list_reset(window_list_t *window_list);
|
||||||
|
|
||||||
|
void window_grab_keys(
|
||||||
|
backend_t *backend,
|
||||||
|
xcb_window_t window,
|
||||||
|
const key_bind_t *keys,
|
||||||
|
size_t count
|
||||||
|
);
|
||||||
|
|||||||
@@ -58,11 +58,8 @@ bool config_defaults_build(
|
|||||||
|
|
||||||
auto default_mode = api->add_mode(builder, "default");
|
auto default_mode = api->add_mode(builder, "default");
|
||||||
|
|
||||||
zdwm_action_arg_t launcher_arg = {.str = launcher};
|
|
||||||
api->bind(builder, default_mode, "Mod4+r", spawn, &launcher_arg);
|
|
||||||
|
|
||||||
#define BIND(mode, key, fn, arg) \
|
#define BIND(mode, key, fn, arg) \
|
||||||
api->bind(builder, mode, key, fn, &(zdwm_action_arg_t)arg)
|
api->bind(builder, mode, key, fn, (zdwm_action_arg_t)arg)
|
||||||
|
|
||||||
BIND(default_mode, "Mod4+r", spawn, {.str = launcher});
|
BIND(default_mode, "Mod4+r", spawn, {.str = launcher});
|
||||||
|
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ static bool runtime_config_bind(
|
|||||||
zdwm_binding_mode_id_t mode,
|
zdwm_binding_mode_id_t mode,
|
||||||
const char *key,
|
const char *key,
|
||||||
zdwm_action_fn fn,
|
zdwm_action_fn fn,
|
||||||
zdwm_action_arg_t *arg
|
zdwm_action_arg_t arg
|
||||||
) {
|
) {
|
||||||
return binding_table_add_bind(builder->binding_table, mode, key, fn, arg);
|
return binding_table_add_bind(builder->binding_table, mode, key, fn, arg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,15 +12,7 @@
|
|||||||
#include "base/array.h"
|
#include "base/array.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "base/memory.h"
|
#include "base/memory.h"
|
||||||
#include "core/event.h"
|
#include "core/types.h"
|
||||||
|
|
||||||
typedef struct key_binding_t {
|
|
||||||
const char *key_str;
|
|
||||||
modifier_mask_t modifiers;
|
|
||||||
xkb_keysym_t keysym;
|
|
||||||
zdwm_action_fn *fn;
|
|
||||||
zdwm_action_arg_t *arg;
|
|
||||||
} key_binding_t;
|
|
||||||
|
|
||||||
typedef struct binding_mode_t {
|
typedef struct binding_mode_t {
|
||||||
zdwm_binding_mode_id_t id;
|
zdwm_binding_mode_id_t id;
|
||||||
@@ -175,7 +167,7 @@ bool binding_table_add_bind(
|
|||||||
zdwm_binding_mode_id_t mode_id,
|
zdwm_binding_mode_id_t mode_id,
|
||||||
const char *key_sequence,
|
const char *key_sequence,
|
||||||
zdwm_action_fn fn,
|
zdwm_action_fn fn,
|
||||||
zdwm_action_arg_t *arg
|
zdwm_action_arg_t arg
|
||||||
) {
|
) {
|
||||||
binding_mode_t *mode = binding_table_get_mode(table, mode_id);
|
binding_mode_t *mode = binding_table_get_mode(table, mode_id);
|
||||||
if (!mode) return false;
|
if (!mode) return false;
|
||||||
@@ -271,3 +263,12 @@ bool binding_table_cycle_mode(binding_table_t *table, int delta) {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const key_binding_t *
|
||||||
|
binding_table_get_current_bindings(binding_table_t *table, size_t *count) {
|
||||||
|
auto mode = binding_table_get_mode(table, table->current_mode);
|
||||||
|
if (!mode || !mode->count) return nullptr;
|
||||||
|
|
||||||
|
*count = mode->count;
|
||||||
|
return mode->items;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,21 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <zdwm/action.h>
|
#include <zdwm/action.h>
|
||||||
#include <zdwm/types.h>
|
#include <zdwm/types.h>
|
||||||
|
|
||||||
|
#include "core/types.h"
|
||||||
|
|
||||||
typedef struct binding_table_t binding_table_t;
|
typedef struct binding_table_t binding_table_t;
|
||||||
|
|
||||||
|
typedef struct key_binding_t {
|
||||||
|
const char *key_str;
|
||||||
|
modifier_mask_t modifiers;
|
||||||
|
keysym_t keysym;
|
||||||
|
zdwm_action_fn *fn;
|
||||||
|
zdwm_action_arg_t arg;
|
||||||
|
} key_binding_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 添加新的模式
|
* @brief 添加新的模式
|
||||||
*
|
*
|
||||||
@@ -36,7 +47,7 @@ bool binding_table_add_bind(
|
|||||||
zdwm_binding_mode_id_t mode_id,
|
zdwm_binding_mode_id_t mode_id,
|
||||||
const char *key_sequence,
|
const char *key_sequence,
|
||||||
zdwm_action_fn fn,
|
zdwm_action_fn fn,
|
||||||
zdwm_action_arg_t *arg
|
zdwm_action_arg_t arg
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,3 +95,18 @@ bool binding_table_set_current_mode(
|
|||||||
* @return 无法切换返回 false 否则返回 true
|
* @return 无法切换返回 false 否则返回 true
|
||||||
*/
|
*/
|
||||||
bool binding_table_cycle_mode(binding_table_t *table, int delta);
|
bool binding_table_cycle_mode(binding_table_t *table, int delta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取当前按键绑定列表
|
||||||
|
*
|
||||||
|
* @param table 按键绑定表
|
||||||
|
* @param count 保存按键个数的指针
|
||||||
|
*
|
||||||
|
* @return 返回当前按键列表的头指针,调用方仅只读访问,不持有对应的内存。
|
||||||
|
*
|
||||||
|
* @notice
|
||||||
|
* 1. count 指针不能为 nullptr ,若 count 传 nullptr 视为调用方错误
|
||||||
|
* 2. 调用方需判断返回的指针是否为 nullptr
|
||||||
|
*/
|
||||||
|
const key_binding_t *
|
||||||
|
binding_table_get_current_bindings(binding_table_t *table, size_t *count);
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ typedef enum event_type_t {
|
|||||||
ZDWM_EVENT_CONFIGURE_REQUEST,
|
ZDWM_EVENT_CONFIGURE_REQUEST,
|
||||||
} event_type_t;
|
} event_type_t;
|
||||||
|
|
||||||
typedef uint32_t modifier_mask_t;
|
|
||||||
typedef uint32_t keysym_t;
|
|
||||||
|
|
||||||
typedef struct key_press_event_t {
|
typedef struct key_press_event_t {
|
||||||
modifier_mask_t modifiers;
|
modifier_mask_t modifiers;
|
||||||
keysym_t keysym;
|
keysym_t keysym;
|
||||||
|
|||||||
@@ -1,16 +1,39 @@
|
|||||||
#include "core/plan.h"
|
#include "core/plan.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "base/array.h"
|
#include "base/array.h"
|
||||||
#include "base/memory.h"
|
#include "base/memory.h"
|
||||||
|
|
||||||
|
static void free_memory_hold_by_effects(effect_t *effects, size_t count) {
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
auto effect = &effects[i];
|
||||||
|
|
||||||
|
switch (effect->type) {
|
||||||
|
case ZDWM_EFFECT_CHANGE_WINDOW_LIST:
|
||||||
|
p_delete(&effect->as.change_window_list.windows);
|
||||||
|
break;
|
||||||
|
case ZDWM_EFFECT_RESTACK_WINDOWS:
|
||||||
|
p_delete(&effect->as.restack_windows.windows);
|
||||||
|
break;
|
||||||
|
case ZDWM_EFFECT_BIND_KEY:
|
||||||
|
p_delete(&effect->as.bind_key.keys);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void plan_reset(plan_t *plan) {
|
void plan_reset(plan_t *plan) {
|
||||||
if (!plan->effects || !plan->capacity) return;
|
if (!plan->effects || !plan->capacity) return;
|
||||||
|
|
||||||
|
free_memory_hold_by_effects(plan->effects, plan->count);
|
||||||
p_clear(plan->effects, plan->capacity);
|
p_clear(plan->effects, plan->capacity);
|
||||||
plan->count = 0;
|
plan->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void plan_cleanup(plan_t *plan) {
|
void plan_cleanup(plan_t *plan) {
|
||||||
|
free_memory_hold_by_effects(plan->effects, plan->count);
|
||||||
p_delete(&plan->effects);
|
p_delete(&plan->effects);
|
||||||
plan->count = 0;
|
plan->count = 0;
|
||||||
plan->capacity = 0;
|
plan->capacity = 0;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ typedef enum effect_type_t {
|
|||||||
ZDWM_EFFECT_CHANGE_BORDER_WIDTH,
|
ZDWM_EFFECT_CHANGE_BORDER_WIDTH,
|
||||||
ZDWM_EFFECT_CHANGE_WINDOW_LIST,
|
ZDWM_EFFECT_CHANGE_WINDOW_LIST,
|
||||||
ZDWM_EFFECT_RESTACK_WINDOWS,
|
ZDWM_EFFECT_RESTACK_WINDOWS,
|
||||||
|
ZDWM_EFFECT_BIND_KEY,
|
||||||
} effect_type_t;
|
} effect_type_t;
|
||||||
|
|
||||||
typedef struct effect_only_window_id_t {
|
typedef struct effect_only_window_id_t {
|
||||||
@@ -48,6 +49,11 @@ typedef struct effect_window_list_t {
|
|||||||
size_t count;
|
size_t count;
|
||||||
} effect_window_list_t;
|
} effect_window_list_t;
|
||||||
|
|
||||||
|
typedef struct effect_bind_key_t {
|
||||||
|
const key_bind_t *keys;
|
||||||
|
size_t count;
|
||||||
|
} effect_bind_key_t;
|
||||||
|
|
||||||
typedef struct effect_t {
|
typedef struct effect_t {
|
||||||
effect_type_t type;
|
effect_type_t type;
|
||||||
union {
|
union {
|
||||||
@@ -61,6 +67,7 @@ typedef struct effect_t {
|
|||||||
effect_change_border_width_t change_border_width;
|
effect_change_border_width_t change_border_width;
|
||||||
effect_window_list_t change_window_list;
|
effect_window_list_t change_window_list;
|
||||||
effect_window_list_t restack_windows;
|
effect_window_list_t restack_windows;
|
||||||
|
effect_bind_key_t bind_key;
|
||||||
} as;
|
} as;
|
||||||
} effect_t;
|
} effect_t;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <zdwm/types.h>
|
#include <zdwm/types.h>
|
||||||
|
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
|
#include "core/binding.h"
|
||||||
#include "core/command.h"
|
#include "core/command.h"
|
||||||
#include "core/command_buffer.h"
|
#include "core/command_buffer.h"
|
||||||
#include "core/event.h"
|
#include "core/event.h"
|
||||||
@@ -14,6 +15,23 @@
|
|||||||
#include "core/window.h"
|
#include "core/window.h"
|
||||||
#include "core/wm_desc.h"
|
#include "core/wm_desc.h"
|
||||||
|
|
||||||
|
static void route_key_press(
|
||||||
|
binding_table_t *binding_table,
|
||||||
|
const zdwm_action_ctx_t *action_ctx,
|
||||||
|
const key_press_event_t *e
|
||||||
|
) {
|
||||||
|
size_t count = 0;
|
||||||
|
auto bindings = binding_table_get_current_bindings(binding_table, &count);
|
||||||
|
if (!bindings) return;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
auto binding = &bindings[i];
|
||||||
|
if (binding->modifiers == e->modifiers && binding->keysym == e->keysym) {
|
||||||
|
binding->fn(action_ctx, &binding->arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static workspace_id_t derive_window_workspace(const state_t *state) {
|
static workspace_id_t derive_window_workspace(const state_t *state) {
|
||||||
return state->outputs[state->current_output_index].current_workspace_id;
|
return state->outputs[state->current_output_index].current_workspace_id;
|
||||||
}
|
}
|
||||||
@@ -115,6 +133,9 @@ void policy_route_event(
|
|||||||
) {
|
) {
|
||||||
auto state = ctx->state;
|
auto state = ctx->state;
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
|
case ZDWM_EVENT_KEY_PRESS:
|
||||||
|
route_key_press(ctx->bind_table, &ctx->action_ctx, &event->as.key_press);
|
||||||
|
break;
|
||||||
case ZDWM_EVENT_WINDOW_MAP_REQUEST:
|
case ZDWM_EVENT_WINDOW_MAP_REQUEST:
|
||||||
route_map_request(state, ctx->rules, &event->as.window_map_request, out);
|
route_map_request(state, ctx->rules, &event->as.window_map_request, out);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <zdwm/action.h>
|
#include <zdwm/action.h>
|
||||||
|
|
||||||
|
#include "core/binding.h"
|
||||||
#include "core/command_buffer.h"
|
#include "core/command_buffer.h"
|
||||||
#include "core/event.h"
|
#include "core/event.h"
|
||||||
#include "core/plan.h"
|
#include "core/plan.h"
|
||||||
@@ -8,6 +10,7 @@
|
|||||||
#include "core/state.h"
|
#include "core/state.h"
|
||||||
|
|
||||||
typedef struct policy_context_t {
|
typedef struct policy_context_t {
|
||||||
|
binding_table_t *bind_table;
|
||||||
state_t *state;
|
state_t *state;
|
||||||
const rules_t *rules;
|
const rules_t *rules;
|
||||||
const zdwm_action_ctx_t action_ctx;
|
const zdwm_action_ctx_t action_ctx;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "core/runtime.h"
|
#include "core/runtime.h"
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "action.h"
|
#include "action.h"
|
||||||
#include "base/memory.h"
|
#include "base/memory.h"
|
||||||
@@ -13,6 +14,7 @@
|
|||||||
#include "core/policy.h"
|
#include "core/policy.h"
|
||||||
#include "core/rules.h"
|
#include "core/rules.h"
|
||||||
#include "core/state.h"
|
#include "core/state.h"
|
||||||
|
#include "core/types.h"
|
||||||
#include "core/wm_desc.h"
|
#include "core/wm_desc.h"
|
||||||
|
|
||||||
static bool runtime_workspace_desc_has_valid_layouts(
|
static bool runtime_workspace_desc_has_valid_layouts(
|
||||||
@@ -112,6 +114,32 @@ void runtime_shutdown(runtime_t *runtime) {
|
|||||||
runtime->config_module_handle = nullptr;
|
runtime->config_module_handle = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void runtime_setup(runtime_t *runtime) {
|
||||||
|
size_t bind_count = 0;
|
||||||
|
auto bindings =
|
||||||
|
binding_table_get_current_bindings(runtime->binding_table, &bind_count);
|
||||||
|
if (!bindings) return;
|
||||||
|
|
||||||
|
auto backend = runtime->backend;
|
||||||
|
auto plan = &runtime->plan;
|
||||||
|
|
||||||
|
plan_reset(plan);
|
||||||
|
|
||||||
|
auto keys = p_new(key_bind_t, bind_count);
|
||||||
|
for (size_t i = 0; i < bind_count; ++i) {
|
||||||
|
keys[i].keysym = bindings[i].keysym;
|
||||||
|
keys[i].modifiers = bindings[i].modifiers;
|
||||||
|
}
|
||||||
|
effect_t effect_bind_key = {
|
||||||
|
.type = ZDWM_EFFECT_BIND_KEY,
|
||||||
|
.as.bind_key = {.count = bind_count, .keys = keys},
|
||||||
|
};
|
||||||
|
plan_push_effect(plan, &effect_bind_key);
|
||||||
|
|
||||||
|
backend_apply_effect(backend, plan->effects, plan->count);
|
||||||
|
plan_reset(plan);
|
||||||
|
}
|
||||||
|
|
||||||
void runtime_run(runtime_t *runtime) {
|
void runtime_run(runtime_t *runtime) {
|
||||||
runtime->running = true;
|
runtime->running = true;
|
||||||
|
|
||||||
@@ -120,6 +148,7 @@ void runtime_run(runtime_t *runtime) {
|
|||||||
plan_t *plan = &runtime->plan;
|
plan_t *plan = &runtime->plan;
|
||||||
|
|
||||||
policy_context_t ctx = {
|
policy_context_t ctx = {
|
||||||
|
.bind_table = runtime->binding_table,
|
||||||
.state = &runtime->state,
|
.state = &runtime->state,
|
||||||
.rules = &runtime->rules,
|
.rules = &runtime->rules,
|
||||||
.action_ctx = {
|
.action_ctx = {
|
||||||
|
|||||||
@@ -40,4 +40,5 @@ typedef struct runtime_t {
|
|||||||
bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc);
|
bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc);
|
||||||
void runtime_init_desc_cleanup(runtime_init_desc_t *desc);
|
void runtime_init_desc_cleanup(runtime_init_desc_t *desc);
|
||||||
void runtime_shutdown(runtime_t *runtime);
|
void runtime_shutdown(runtime_t *runtime);
|
||||||
|
void runtime_setup(runtime_t *runtime);
|
||||||
void runtime_run(runtime_t *runtime);
|
void runtime_run(runtime_t *runtime);
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ typedef zdwm_rule_match_t rule_match_t;
|
|||||||
typedef zdwm_rule_action_t rule_action_t;
|
typedef zdwm_rule_action_t rule_action_t;
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
|
typedef uint32_t modifier_mask_t;
|
||||||
|
typedef uint32_t keysym_t;
|
||||||
|
|
||||||
#define ZDWM_OUTPUT_ID_INVALID ((output_id_t)UINT32_MAX)
|
#define ZDWM_OUTPUT_ID_INVALID ((output_id_t)UINT32_MAX)
|
||||||
|
|
||||||
typedef struct point_t {
|
typedef struct point_t {
|
||||||
@@ -59,3 +62,8 @@ typedef enum modifier_bit_t {
|
|||||||
ZDWM_MOD_4 = 1u << 5,
|
ZDWM_MOD_4 = 1u << 5,
|
||||||
ZDWM_MOD_5 = 1u << 6,
|
ZDWM_MOD_5 = 1u << 6,
|
||||||
} modifier_bit_t;
|
} modifier_bit_t;
|
||||||
|
|
||||||
|
typedef struct key_bind_t {
|
||||||
|
modifier_mask_t modifiers;
|
||||||
|
keysym_t keysym;
|
||||||
|
} key_bind_t;
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ int main(void) {
|
|||||||
runtime_t runtime = {0};
|
runtime_t runtime = {0};
|
||||||
|
|
||||||
bootstrap(&runtime);
|
bootstrap(&runtime);
|
||||||
|
runtime_setup(&runtime);
|
||||||
runtime_run(&runtime);
|
runtime_run(&runtime);
|
||||||
runtime_shutdown(&runtime);
|
runtime_shutdown(&runtime);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user