feat(backend): 支持鼠标抓取功能
This commit is contained in:
@@ -522,6 +522,22 @@ backend_bind_key(backend_t *backend, const effect_bind_key_t *bind_key) {
|
||||
window_grab_keys(backend, root, bind_key->keys, bind_key->count);
|
||||
}
|
||||
|
||||
static void backend_grab_button(
|
||||
backend_t *backend,
|
||||
const effect_grab_button_t *grab_button
|
||||
) {
|
||||
auto conn = backend->conn;
|
||||
auto window = grab_button->window;
|
||||
xcb_ungrab_button(conn, XCB_BUTTON_INDEX_ANY, window, XCB_MOD_MASK_ANY);
|
||||
|
||||
auto buttons = grab_button->buttons;
|
||||
for (size_t i = 0; i < grab_button->count; ++i) {
|
||||
auto button = buttons[i].button;
|
||||
auto modifiers = buttons[i].modifiers;
|
||||
window_grab_button(backend, window, button, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
static void backend_merge_effects(
|
||||
backend_t *backend,
|
||||
const effect_t *effects,
|
||||
@@ -601,6 +617,8 @@ static void backend_merge_effects(
|
||||
case ZDWM_EFFECT_BIND_KEY:
|
||||
backend_bind_key(backend, &e->as.bind_key);
|
||||
break;
|
||||
case ZDWM_EFFECT_GRAB_BUTTON:
|
||||
backend_grab_button(backend, &e->as.grab_button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
71
src/backend/x11/common.c
Normal file
71
src/backend/x11/common.c
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "common.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <xcb/xproto.h>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "core/types.h"
|
||||
|
||||
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},
|
||||
};
|
||||
|
||||
modifier_mask_t modifiers_xcb_to_zdwm(uint16_t mask) {
|
||||
modifier_mask_t 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;
|
||||
}
|
||||
|
||||
uint16_t modifiers_zdwm_to_xcb(modifier_mask_t mask) {
|
||||
uint16_t mods = 0U;
|
||||
for (size_t i = 0; i < countof(modifier_map); ++i) {
|
||||
auto item = &modifier_map[i];
|
||||
if (mask & item->modifier) mods |= item->mask;
|
||||
}
|
||||
return mods;
|
||||
}
|
||||
|
||||
typedef struct button_map_t {
|
||||
button_t zdwm_button;
|
||||
xcb_button_index_t xcb_button;
|
||||
} button_map_t;
|
||||
|
||||
static constexpr button_map_t button_map[] = {
|
||||
{ZDWM_BUTTON_LEFT, XCB_BUTTON_INDEX_1},
|
||||
{ZDWM_BUTTON_RIGHT, XCB_BUTTON_INDEX_3},
|
||||
{ZDWM_BUTTON_MIDDLE, XCB_BUTTON_INDEX_2},
|
||||
/* TODO: 后续可以考虑加上鼠标滚轮事件 */
|
||||
};
|
||||
|
||||
button_t button_xcb_to_zdwm(xcb_button_t button) {
|
||||
for (size_t i = 0; i < countof(button_map); ++i) {
|
||||
auto item = &button_map[i];
|
||||
if (button == item->xcb_button) return item->zdwm_button;
|
||||
}
|
||||
|
||||
return ZDWM_BUTTON_NONE;
|
||||
}
|
||||
|
||||
xcb_button_t button_zdwm_to_xcb(button_t button) {
|
||||
for (size_t i = 0; i < countof(button_map); ++i) {
|
||||
auto item = &button_map[i];
|
||||
if (button == item->zdwm_button) return item->xcb_button;
|
||||
}
|
||||
|
||||
return XCB_BUTTON_INDEX_ANY;
|
||||
}
|
||||
12
src/backend/x11/common.h
Normal file
12
src/backend/x11/common.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <xcb/xproto.h>
|
||||
|
||||
#include "core/types.h"
|
||||
|
||||
modifier_mask_t modifiers_xcb_to_zdwm(uint16_t mask);
|
||||
uint16_t modifiers_zdwm_to_xcb(modifier_mask_t mask);
|
||||
|
||||
button_t button_xcb_to_zdwm(xcb_button_t button);
|
||||
xcb_button_t button_zdwm_to_xcb(button_t button);
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <xcb/xcb_keysyms.h>
|
||||
#include <xcb/xproto.h>
|
||||
|
||||
#include "backend/x11/common.h"
|
||||
#include "backend/x11/window.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory.h"
|
||||
#include "core/backend.h"
|
||||
#include "core/types.h"
|
||||
@@ -233,29 +233,6 @@ static bool handle_configure_request(
|
||||
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,
|
||||
@@ -269,39 +246,18 @@ static bool handle_key_press(
|
||||
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);
|
||||
event->as.key_press.modifiers = modifiers_xcb_to_zdwm(xcb_event->state);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool get_button(xcb_button_t button_detail, uint32_t *button) {
|
||||
assert(button != nullptr);
|
||||
switch (button_detail) {
|
||||
case XCB_BUTTON_INDEX_1:
|
||||
*button = ZDWM_BUTTON_LEFT;
|
||||
return true;
|
||||
case XCB_BUTTON_INDEX_2:
|
||||
*button = ZDWM_BUTTON_RIGHT;
|
||||
return true;
|
||||
case XCB_BUTTON_INDEX_3:
|
||||
*button = ZDWM_BUTTON_MIDDLE;
|
||||
return true;
|
||||
case XCB_BUTTON_INDEX_4:
|
||||
case XCB_BUTTON_INDEX_5:
|
||||
/* TODO: 后续可以考虑加上鼠标滚轮事件 */
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool fill_button_event(
|
||||
const xcb_button_press_event_t *xcb_event,
|
||||
pointer_button_event_t *data
|
||||
) {
|
||||
uint32_t button = 0;
|
||||
if (!get_button(xcb_event->detail, &button)) return false;
|
||||
auto button = button_xcb_to_zdwm(xcb_event->detail);
|
||||
|
||||
data->modifiers = get_modifiers(xcb_event->state);
|
||||
data->modifiers = modifiers_xcb_to_zdwm(xcb_event->state);
|
||||
data->button = button;
|
||||
data->window = xcb_event->event;
|
||||
data->root = (point_t){.x = xcb_event->root_x, .y = xcb_event->root_y};
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <xcb/xcb_keysyms.h>
|
||||
#include <xcb/xproto.h>
|
||||
|
||||
#include "backend/x11/common.h"
|
||||
#include "backend/x11/cursor.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory.h"
|
||||
@@ -463,3 +464,26 @@ void window_change_cursor(
|
||||
xcb_params_cw_t params = {.cursor = cursor_get_xcb_cursor(backend, cursor)};
|
||||
xcb_aux_change_window_attributes(conn, window, XCB_CW_CURSOR, ¶ms);
|
||||
}
|
||||
|
||||
void window_grab_button(
|
||||
backend_t *backend,
|
||||
xcb_window_t window,
|
||||
button_t button,
|
||||
modifier_mask_t modifiers
|
||||
) {
|
||||
auto xcb_button = button_zdwm_to_xcb(button);
|
||||
if (xcb_button == XCB_BUTTON_INDEX_ANY) return;
|
||||
|
||||
xcb_grab_button(
|
||||
backend->conn,
|
||||
false, /* 事件仅发送给抓取者,不发送给其他窗口 */
|
||||
window,
|
||||
XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE,
|
||||
XCB_GRAB_MODE_ASYNC,
|
||||
XCB_GRAB_MODE_SYNC,
|
||||
XCB_WINDOW_NONE,
|
||||
XCB_CURSOR_NONE,
|
||||
xcb_button,
|
||||
modifiers_zdwm_to_xcb(modifiers)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -124,3 +124,10 @@ void window_change_cursor(
|
||||
xcb_window_t window,
|
||||
cursor_t cursor
|
||||
);
|
||||
|
||||
void window_grab_button(
|
||||
backend_t *backend,
|
||||
xcb_window_t window,
|
||||
button_t button,
|
||||
modifier_mask_t modifiers
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user