Compare commits
6 Commits
b40f499e7b
...
c6ade0144c
| Author | SHA1 | Date | |
|---|---|---|---|
|
c6ade0144c
|
|||
|
6d9ff81f78
|
|||
|
0626a4c512
|
|||
|
4500a5adfd
|
|||
|
9315505085
|
|||
|
bec2162890
|
3
Makefile
3
Makefile
@@ -28,13 +28,14 @@ wm: $(TARGET_NAME)
|
|||||||
DISPLAY=:3 $(TARGET)
|
DISPLAY=:3 $(TARGET)
|
||||||
|
|
||||||
debug: $(TARGET_NAME)
|
debug: $(TARGET_NAME)
|
||||||
DISPLAY=:3 valgrind $(TARGET)
|
DISPLAY=:3 valgrind --leak-check=full $(TARGET)
|
||||||
|
|
||||||
prepare:
|
prepare:
|
||||||
@cmake -S $(SRC_DIR) -B $(BUILD_DIR)
|
@cmake -S $(SRC_DIR) -B $(BUILD_DIR)
|
||||||
@cp $(BUILD_DIR)/compile_commands.json $(MAKEFILE_DIR)
|
@cp $(BUILD_DIR)/compile_commands.json $(MAKEFILE_DIR)
|
||||||
|
|
||||||
build: prepare
|
build: prepare
|
||||||
|
${RM} -f $(TARGET)
|
||||||
@cmake --build $(BUILD_DIR)
|
@cmake --build $(BUILD_DIR)
|
||||||
@cp $(BUILD_DIR)/$(TARGET_NAME) $(TARGET)
|
@cp $(BUILD_DIR)/$(TARGET_NAME) $(TARGET)
|
||||||
|
|
||||||
|
|||||||
21
TODO.org
Normal file
21
TODO.org
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#+title: zswm 代办事项
|
||||||
|
|
||||||
|
* TODO 调整光标在每个 monitor 中最后停留位置的逻辑
|
||||||
|
因为在有些程序(如 Emacs 和 Firefox)中移动鼠标不会触发 motion_notify 事件,
|
||||||
|
因此需调整记录每个 monitor 中光标最后停留位置的逻辑,不能将 motion_notify 事件作为唯一依赖。
|
||||||
|
|
||||||
|
可在切换屏幕时主动查询当前光标,将其位置记录到切换前的 monitor 中。
|
||||||
|
|
||||||
|
* TODO 处理鼠标点击 bar_window 事件
|
||||||
|
|
||||||
|
* TODO 处理鼠标移动窗口事件
|
||||||
|
|
||||||
|
* TODO 处理鼠标调整窗口大小事件
|
||||||
|
|
||||||
|
* TODO 调整 stack 顺序和焦点逻辑,总感觉现在的情况有 bug
|
||||||
|
|
||||||
|
* TODO 调整 stack 逻辑,让 bar_window 在最底部
|
||||||
|
|
||||||
|
* TODO 添加切换布局算法功能
|
||||||
|
|
||||||
|
* TODO 添加系统托盘显示
|
||||||
@@ -12,6 +12,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||||||
# compile flags
|
# compile flags
|
||||||
add_compile_options(-g)
|
add_compile_options(-g)
|
||||||
add_compile_options(-Wall)
|
add_compile_options(-Wall)
|
||||||
|
# add_link_options(-fsanitize=address)
|
||||||
|
|
||||||
project(${APP_NAME}
|
project(${APP_NAME}
|
||||||
VERSION 0.0.1
|
VERSION 0.0.1
|
||||||
|
|||||||
@@ -40,8 +40,15 @@ typedef enum notify_detail_t {
|
|||||||
notify_detail_none = 7,
|
notify_detail_none = 7,
|
||||||
} notify_detail_t;
|
} notify_detail_t;
|
||||||
|
|
||||||
|
typedef enum mapping_t {
|
||||||
|
MAPPING_MODIFIER = 0,
|
||||||
|
MAPPING_KEYBOARD = 1,
|
||||||
|
MAPPING_POINTER = 2
|
||||||
|
} mapping_t;
|
||||||
|
|
||||||
typedef struct mapping_notify_event_t {
|
typedef struct mapping_notify_event_t {
|
||||||
event_type_t type;
|
event_type_t type;
|
||||||
|
mapping_t request;
|
||||||
} mapping_notify_event_t;
|
} mapping_notify_event_t;
|
||||||
|
|
||||||
typedef struct key_press_event_t {
|
typedef struct key_press_event_t {
|
||||||
@@ -52,6 +59,10 @@ typedef struct key_press_event_t {
|
|||||||
|
|
||||||
typedef struct button_press_event_t {
|
typedef struct button_press_event_t {
|
||||||
event_type_t type;
|
event_type_t type;
|
||||||
|
xcb_window_t window;
|
||||||
|
xcb_window_t root;
|
||||||
|
int32_t x, y, root_x, root_y;
|
||||||
|
uint32_t time; /* 时间戳(单位:ms) */
|
||||||
} button_press_event_t;
|
} button_press_event_t;
|
||||||
|
|
||||||
typedef struct configure_request_event_t {
|
typedef struct configure_request_event_t {
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ typedef enum atom_t {
|
|||||||
atom_zswm_client_info, /* 自定义属性,用于存储所在 monitor 和 tags */
|
atom_zswm_client_info, /* 自定义属性,用于存储所在 monitor 和 tags */
|
||||||
} atom_t;
|
} atom_t;
|
||||||
xcb_atom_t get_xcb_atom(atom_t atom);
|
xcb_atom_t get_xcb_atom(atom_t atom);
|
||||||
|
char *get_xcb_atom_name(xcb_atom_t atom);
|
||||||
bool send_event(xcb_window_t window, atom_t atom);
|
bool send_event(xcb_window_t window, atom_t atom);
|
||||||
typedef enum wm_state_t {
|
typedef enum wm_state_t {
|
||||||
wm_state_withdrawn = 0,
|
wm_state_withdrawn = 0,
|
||||||
|
|||||||
12
src/main.c
12
src/main.c
@@ -926,8 +926,10 @@ void focus_in(focus_in_event_t *event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void property_notify(property_notify_event_t *event) {
|
void property_notify(property_notify_event_t *event) {
|
||||||
logger("window: 0x%x state: %u, atom: %u\n", event->window, event->state,
|
char *atom_name = get_xcb_atom_name(event->xcb_atom);
|
||||||
event->xcb_atom);
|
logger("window: 0x%x state: %u, atom: %u, atom name: %s\n", event->window,
|
||||||
|
event->state, event->xcb_atom, atom_name);
|
||||||
|
free(atom_name);
|
||||||
if (event->state == property_delete) return;
|
if (event->state == property_delete) return;
|
||||||
|
|
||||||
client_t *c = get_client_of_window(event->window);
|
client_t *c = get_client_of_window(event->window);
|
||||||
@@ -956,6 +958,10 @@ void property_notify(property_notify_event_t *event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void client_message(client_message_event_t *event) {
|
void client_message(client_message_event_t *event) {
|
||||||
|
char *atom_name = get_xcb_atom_name(event->message_type);
|
||||||
|
logger("client message: message type: %s\n", atom_name);
|
||||||
|
free(atom_name);
|
||||||
|
|
||||||
client_t *c = get_client_of_window(event->window);
|
client_t *c = get_client_of_window(event->window);
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
|
|
||||||
@@ -1014,6 +1020,8 @@ void manage_window(xcb_window_t window) {
|
|||||||
c->height = c->old_height = geometry->height;
|
c->height = c->old_height = geometry->height;
|
||||||
c->old_border_width = geometry->border_width;
|
c->old_border_width = geometry->border_width;
|
||||||
c->border_width = border_px;
|
c->border_width = border_px;
|
||||||
|
free(geometry);
|
||||||
|
|
||||||
update_client_name(c);
|
update_client_name(c);
|
||||||
|
|
||||||
logger("== manage window: 0x%x\n", window);
|
logger("== manage window: 0x%x\n", window);
|
||||||
|
|||||||
@@ -18,11 +18,13 @@ struct event_adapter_t {
|
|||||||
static void convert_event(xcb_generic_event_t *xcb_event,
|
static void convert_event(xcb_generic_event_t *xcb_event,
|
||||||
generic_event_t *event) {
|
generic_event_t *event) {
|
||||||
uint8_t event_type = XCB_EVENT_RESPONSE_TYPE(xcb_event);
|
uint8_t event_type = XCB_EVENT_RESPONSE_TYPE(xcb_event);
|
||||||
const char *label = xcb_event_get_label(event_type);
|
|
||||||
switch (event_type) {
|
switch (event_type) {
|
||||||
case XCB_MAPPING_NOTIFY:
|
case XCB_MAPPING_NOTIFY: {
|
||||||
event->type = EVENT_TYPE_MAPPING_NOTIFY;
|
xcb_mapping_notify_event_t *ev = (xcb_mapping_notify_event_t *)xcb_event;
|
||||||
|
event->mapping_notify.type = EVENT_TYPE_MAPPING_NOTIFY;
|
||||||
|
event->mapping_notify.request = ev->request;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case XCB_KEY_PRESS: {
|
case XCB_KEY_PRESS: {
|
||||||
xcb_key_press_event_t *ev = (xcb_key_press_event_t *)xcb_event;
|
xcb_key_press_event_t *ev = (xcb_key_press_event_t *)xcb_event;
|
||||||
int col = ev->state & XCB_MOD_MASK_2 ? 1 : 0;
|
int col = ev->state & XCB_MOD_MASK_2 ? 1 : 0;
|
||||||
@@ -32,9 +34,18 @@ static void convert_event(xcb_generic_event_t *xcb_event,
|
|||||||
event->key_press.modifiers = ev->state;
|
event->key_press.modifiers = ev->state;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case XCB_BUTTON_PRESS:
|
case XCB_BUTTON_PRESS: {
|
||||||
event->type = EVENT_TYPE_BUTTON_PRESS;
|
xcb_button_press_event_t *ev = (xcb_button_press_event_t *)xcb_event;
|
||||||
|
event->button_press.type = EVENT_TYPE_BUTTON_PRESS;
|
||||||
|
event->button_press.window = ev->event;
|
||||||
|
event->button_press.root = ev->root;
|
||||||
|
event->button_press.x = ev->event_x;
|
||||||
|
event->button_press.y = ev->event_y;
|
||||||
|
event->button_press.root_x = ev->root_x;
|
||||||
|
event->button_press.root_y = ev->root_y;
|
||||||
|
event->button_press.time = ev->time;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case XCB_CONFIGURE_REQUEST: {
|
case XCB_CONFIGURE_REQUEST: {
|
||||||
xcb_configure_request_event_t *ev =
|
xcb_configure_request_event_t *ev =
|
||||||
(xcb_configure_request_event_t *)xcb_event;
|
(xcb_configure_request_event_t *)xcb_event;
|
||||||
@@ -66,7 +77,8 @@ static void convert_event(xcb_generic_event_t *xcb_event,
|
|||||||
event->unmap_notify.type = EVENT_TYPE_UNMAP_NOTIFY;
|
event->unmap_notify.type = EVENT_TYPE_UNMAP_NOTIFY;
|
||||||
event->unmap_notify.window = ev->window;
|
event->unmap_notify.window = ev->window;
|
||||||
event->unmap_notify.send_event = XCB_EVENT_SENT(ev);
|
event->unmap_notify.send_event = XCB_EVENT_SENT(ev);
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
case XCB_DESTROY_NOTIFY: {
|
case XCB_DESTROY_NOTIFY: {
|
||||||
xcb_destroy_notify_event_t *ev = (xcb_destroy_notify_event_t *)xcb_event;
|
xcb_destroy_notify_event_t *ev = (xcb_destroy_notify_event_t *)xcb_event;
|
||||||
event->destroy_notify.type = EVENT_TYPE_DESTROY_NOTIFY;
|
event->destroy_notify.type = EVENT_TYPE_DESTROY_NOTIFY;
|
||||||
@@ -127,7 +139,8 @@ static void convert_event(xcb_generic_event_t *xcb_event,
|
|||||||
event->type = -1;
|
event->type = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event->type != EVENT_TYPE_MOTION_NOTIFY) {
|
if (event->type) {
|
||||||
|
const char *label = xcb_event_get_label(event_type);
|
||||||
logger("========================== %s ==========================\n", label);
|
logger("========================== %s ==========================\n", label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -288,11 +288,10 @@ char *get_window_name(xcb_window_t window) {
|
|||||||
|
|
||||||
void set_window_event_mask(xcb_window_t window, bool clear) {
|
void set_window_event_mask(xcb_window_t window, bool clear) {
|
||||||
xcb_cw_t change_mask = XCB_CW_EVENT_MASK;
|
xcb_cw_t change_mask = XCB_CW_EVENT_MASK;
|
||||||
uint32_t event_mask = clear ? XCB_EVENT_MASK_NO_EVENT
|
uint32_t init_event_mask =
|
||||||
: XCB_EVENT_MASK_ENTER_WINDOW |
|
XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE |
|
||||||
XCB_EVENT_MASK_FOCUS_CHANGE |
|
XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY;
|
||||||
XCB_EVENT_MASK_PROPERTY_CHANGE |
|
uint32_t event_mask = clear ? XCB_EVENT_MASK_NO_EVENT : init_event_mask;
|
||||||
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY;
|
|
||||||
xcb_params_cw_t params = {.event_mask = event_mask};
|
xcb_params_cw_t params = {.event_mask = event_mask};
|
||||||
xcb_aux_change_window_attributes(conn, window, change_mask, ¶ms);
|
xcb_aux_change_window_attributes(conn, window, change_mask, ¶ms);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,6 +111,23 @@ xcb_atom_t get_xcb_atom(atom_t atom) {
|
|||||||
return atom_map[atom].xcb_atom;
|
return atom_map[atom].xcb_atom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取 xcb atom 名称
|
||||||
|
* @returns xcb atom 对应的名称,使用后记得用 free 释放
|
||||||
|
*/
|
||||||
|
char *get_xcb_atom_name(xcb_atom_t atom) {
|
||||||
|
xcb_get_atom_name_cookie_t cookie = xcb_get_atom_name(conn, atom);
|
||||||
|
xcb_get_atom_name_reply_t *reply =
|
||||||
|
xcb_get_atom_name_reply(conn, cookie, NULL);
|
||||||
|
int length = xcb_get_atom_name_name_length(reply);
|
||||||
|
char *name_buffer = ecalloc(1, length + 1);
|
||||||
|
const char *name = xcb_get_atom_name_name(reply);
|
||||||
|
strncpy(name_buffer, name, length);
|
||||||
|
|
||||||
|
free(reply);
|
||||||
|
return name_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
bool send_event(xcb_window_t window, atom_t atom) {
|
bool send_event(xcb_window_t window, atom_t atom) {
|
||||||
if (atom < 0 || atom >= LENGTH(atom_map)) return false;
|
if (atom < 0 || atom >= LENGTH(atom_map)) return false;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user