记录光标在每个屏幕中最后停留的位置
This commit is contained in:
@@ -164,6 +164,7 @@ const char *const active_border_color = "#005577";
|
|||||||
const char *const default_font_family = "sans-serif, monospace";
|
const char *const default_font_family = "sans-serif, monospace";
|
||||||
const uint32_t default_font_size = 10;
|
const uint32_t default_font_size = 10;
|
||||||
const uint32_t dpi_fallback = 96;
|
const uint32_t dpi_fallback = 96;
|
||||||
|
const uint32_t refresh_rate = 60;
|
||||||
|
|
||||||
const uint32_t bar_y_padding = 1;
|
const uint32_t bar_y_padding = 1;
|
||||||
const uint32_t tag_x_padding = 10;
|
const uint32_t tag_x_padding = 10;
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ typedef struct motion_notify_event_t {
|
|||||||
xcb_window_t window;
|
xcb_window_t window;
|
||||||
int32_t x;
|
int32_t x;
|
||||||
int32_t y;
|
int32_t y;
|
||||||
|
uint32_t time; /* 时间戳(单位:ms) */
|
||||||
} motion_notify_event_t;
|
} motion_notify_event_t;
|
||||||
|
|
||||||
typedef struct enter_notify_event_t {
|
typedef struct enter_notify_event_t {
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ struct monitor_t {
|
|||||||
client_t *clients_stack;
|
client_t *clients_stack;
|
||||||
client_t *selected_client;
|
client_t *selected_client;
|
||||||
|
|
||||||
|
int32_t pointer_x; /* 记录光标 x 坐标位置 */
|
||||||
|
int32_t pointer_y; /* 记录光标 y 坐标位置 */
|
||||||
|
|
||||||
xcb_window_t bar_window;
|
xcb_window_t bar_window;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ void set_window_tag(xcb_window_t window, client_tag_info_t *client_info);
|
|||||||
void remove_window_tag(xcb_window_t window);
|
void remove_window_tag(xcb_window_t window);
|
||||||
|
|
||||||
bool get_pointer_position(int32_t *x, int32_t *y);
|
bool get_pointer_position(int32_t *x, int32_t *y);
|
||||||
|
void set_pointer_position(int32_t x, int32_t y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 非阻塞检查特定事件掩码(模拟 XCheckMaskEvent)
|
* @brief 非阻塞检查特定事件掩码(模拟 XCheckMaskEvent)
|
||||||
|
|||||||
66
src/main.c
66
src/main.c
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
static void init_monitors(void);
|
static void init_monitors(void);
|
||||||
static char **get_monitor_tags(uint32_t monitor_count, uint32_t monitor_index);
|
static char **get_monitor_tags(uint32_t monitor_count, uint32_t monitor_index);
|
||||||
|
static void record_mointor_pointer_position(int32_t x, int32_t y,
|
||||||
|
uint32_t timestamp);
|
||||||
static void init_wallpaper(void);
|
static void init_wallpaper(void);
|
||||||
static gboolean update_wallpaper(gpointer user_data);
|
static gboolean update_wallpaper(gpointer user_data);
|
||||||
static void set_wallpaper_by_index(uint32_t index, wallpaper_config_t *config,
|
static void set_wallpaper_by_index(uint32_t index, wallpaper_config_t *config,
|
||||||
@@ -96,6 +98,7 @@ static event_adapter_t *adapter = NULL;
|
|||||||
static char *font_family = NULL;
|
static char *font_family = NULL;
|
||||||
static uint32_t font_size = default_font_size;
|
static uint32_t font_size = default_font_size;
|
||||||
static uint32_t dpi = dpi_fallback;
|
static uint32_t dpi = dpi_fallback;
|
||||||
|
static uint32_t fps = refresh_rate;
|
||||||
static uint32_t bar_y_pad = bar_y_padding;
|
static uint32_t bar_y_pad = bar_y_padding;
|
||||||
static uint32_t tag_x_pad = tag_x_padding;
|
static uint32_t tag_x_pad = tag_x_padding;
|
||||||
static uint32_t layout_symbol_x_pad = layout_symbol_x_padding;
|
static uint32_t layout_symbol_x_pad = layout_symbol_x_padding;
|
||||||
@@ -174,7 +177,8 @@ void focus_monitor(const user_action_arg_t *arg) {
|
|||||||
unfocus(current_monitor->selected_client, false);
|
unfocus(current_monitor->selected_client, false);
|
||||||
current_monitor = monitor;
|
current_monitor = monitor;
|
||||||
focus(NULL);
|
focus(NULL);
|
||||||
/* TODO: 调整鼠标光标 */
|
|
||||||
|
set_pointer_position(monitor->pointer_x, monitor->pointer_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void raise_or_run(const user_action_arg_t *arg) {
|
void raise_or_run(const user_action_arg_t *arg) {
|
||||||
@@ -187,6 +191,8 @@ void raise_or_run(const user_action_arg_t *arg) {
|
|||||||
logger("==== raise client: %s, window: 0x%x\n", client->name,
|
logger("==== raise client: %s, window: 0x%x\n", client->name,
|
||||||
client->window);
|
client->window);
|
||||||
current_monitor = client->monitor;
|
current_monitor = client->monitor;
|
||||||
|
set_pointer_position(current_monitor->pointer_x,
|
||||||
|
current_monitor->pointer_y);
|
||||||
argument.ui = client->tags;
|
argument.ui = client->tags;
|
||||||
select_tag(&argument);
|
select_tag(&argument);
|
||||||
focus(client);
|
focus(client);
|
||||||
@@ -231,19 +237,22 @@ void move_to_tag(const user_action_arg_t *arg) {
|
|||||||
arrange(current_monitor);
|
arrange(current_monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_monitor_info(monitor_t *monitor) {
|
||||||
|
logger("========== mon[%u]:\n", monitor->index);
|
||||||
|
logger("x: %d, y: %d, width: %u, height: %u, pointer x: %d, pointer y: %d\n",
|
||||||
|
monitor->monitor_x, monitor->monitor_y, monitor->monitor_width,
|
||||||
|
monitor->monitor_height, monitor->pointer_x, monitor->pointer_y);
|
||||||
|
logger("mon[%u] tags: ", monitor->index);
|
||||||
|
for (int i = 0; monitor->tags[i]; i++) {
|
||||||
|
logger("%s%s", i > 0 ? ", " : "", monitor->tags[i]);
|
||||||
|
}
|
||||||
|
logger("\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* 调试函数,开发完成后删除 */
|
/* 调试函数,开发完成后删除 */
|
||||||
static void print_monitor_list_info(monitor_t *monitor_list) {
|
static void print_monitor_list_info(monitor_t *monitor_list) {
|
||||||
logger("========================= monitor info =========================\n");
|
logger("========================= monitor info =========================\n");
|
||||||
for (monitor_t *m = monitor_list; m; m = m->next) {
|
for (monitor_t *m = monitor_list; m; m = m->next) print_monitor_info(m);
|
||||||
logger("========== mon[%u]:\n", m->index);
|
|
||||||
logger("x: %d, y: %d, width: %u, height: %u\n", m->monitor_x, m->monitor_y,
|
|
||||||
m->monitor_width, m->monitor_height);
|
|
||||||
logger("mon[%u] tags: ", m->index);
|
|
||||||
for (int i = 0; m->tags[i]; i++) {
|
|
||||||
logger("%s%s", i > 0 ? ", " : "", m->tags[i]);
|
|
||||||
}
|
|
||||||
logger("\n");
|
|
||||||
}
|
|
||||||
logger("======================= monitor info end =======================\n");
|
logger("======================= monitor info end =======================\n");
|
||||||
}
|
}
|
||||||
static void print_color(const char *prompt, const color_t *color) {
|
static void print_color(const char *prompt, const color_t *color) {
|
||||||
@@ -356,6 +365,25 @@ void init_monitors(void) {
|
|||||||
m->tags = get_monitor_tags(i, m->index);
|
m->tags = get_monitor_tags(i, m->index);
|
||||||
m->selected_tags = 0x1;
|
m->selected_tags = 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t x, y;
|
||||||
|
if (get_pointer_position(&x, &y)) {
|
||||||
|
monitor_t *monitor = rect_to_monitor(monitors, x, y, 1, 1);
|
||||||
|
print_monitor_info(monitor);
|
||||||
|
|
||||||
|
int32_t offset_x = x - monitor->monitor_x;
|
||||||
|
int32_t offset_y = y - monitor->monitor_y;
|
||||||
|
|
||||||
|
logger("==== init monitor pointer position ====\n");
|
||||||
|
logger("x: %d, y: %d, offset_x: %d, offset_y: %d\n", x, y, offset_x,
|
||||||
|
offset_y);
|
||||||
|
logger("== init monitor pointer position end ==\n");
|
||||||
|
|
||||||
|
for (monitor_t *m = monitors; m; m = m->next) {
|
||||||
|
m->pointer_x = m->monitor_x + offset_x;
|
||||||
|
m->pointer_y = m->monitor_y + offset_y;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char **get_monitor_tags(uint32_t monitor_count, uint32_t monitor_index) {
|
char **get_monitor_tags(uint32_t monitor_count, uint32_t monitor_index) {
|
||||||
@@ -385,6 +413,15 @@ char **get_monitor_tags(uint32_t monitor_count, uint32_t monitor_index) {
|
|||||||
return g_strv_builder_unref_to_strv(builder);
|
return g_strv_builder_unref_to_strv(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void record_mointor_pointer_position(int32_t x, int32_t y, uint32_t timestamp) {
|
||||||
|
static uint32_t last_timestamp = 0;
|
||||||
|
if ((timestamp - last_timestamp) < (1000 / fps)) return;
|
||||||
|
|
||||||
|
monitor_t *monitor = rect_to_monitor(monitors, x, y, 1, 1);
|
||||||
|
monitor->pointer_x = x;
|
||||||
|
monitor->pointer_x = y;
|
||||||
|
}
|
||||||
|
|
||||||
void init_wallpaper(void) {
|
void init_wallpaper(void) {
|
||||||
bar_cairo_params_t *p = prepare_wallpaper_surface_params();
|
bar_cairo_params_t *p = prepare_wallpaper_surface_params();
|
||||||
rect_size_t *screen_size = get_screen_size();
|
rect_size_t *screen_size = get_screen_size();
|
||||||
@@ -693,6 +730,7 @@ void init_monitor_bar(void) {
|
|||||||
|
|
||||||
void get_xresource_config(void) {
|
void get_xresource_config(void) {
|
||||||
get_xresource_uint32("Xft.dpi", &dpi);
|
get_xresource_uint32("Xft.dpi", &dpi);
|
||||||
|
get_xresource_uint32("zswm.fps", &fps);
|
||||||
get_xresource_string("zswm.font_family", &font_family, default_font_family);
|
get_xresource_string("zswm.font_family", &font_family, default_font_family);
|
||||||
get_xresource_uint32("zswm.font_size", &font_size);
|
get_xresource_uint32("zswm.font_size", &font_size);
|
||||||
get_xresource_uint32("zswm.bar_y_padding", &bar_y_pad);
|
get_xresource_uint32("zswm.bar_y_padding", &bar_y_pad);
|
||||||
@@ -847,6 +885,8 @@ void expose(expose_event_t *event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void motion_notify(motion_notify_event_t *event) {
|
void motion_notify(motion_notify_event_t *event) {
|
||||||
|
record_mointor_pointer_position(event->root_x, event->root_y, event->time);
|
||||||
|
|
||||||
if (event->window != get_root_window()) return;
|
if (event->window != get_root_window()) return;
|
||||||
|
|
||||||
static monitor_t *mon = NULL;
|
static monitor_t *mon = NULL;
|
||||||
@@ -954,6 +994,8 @@ void client_message(client_message_event_t *event) {
|
|||||||
const user_action_arg_t arg = {.ui = target_tag};
|
const user_action_arg_t arg = {.ui = target_tag};
|
||||||
|
|
||||||
current_monitor = client->monitor;
|
current_monitor = client->monitor;
|
||||||
|
set_pointer_position(current_monitor->pointer_x,
|
||||||
|
current_monitor->pointer_y);
|
||||||
select_tag(&arg);
|
select_tag(&arg);
|
||||||
focus(client);
|
focus(client);
|
||||||
restack(current_monitor);
|
restack(current_monitor);
|
||||||
@@ -1098,6 +1140,8 @@ void apply_rules(client_t *client) {
|
|||||||
}
|
}
|
||||||
if (switch_to_tag) {
|
if (switch_to_tag) {
|
||||||
current_monitor = client->monitor;
|
current_monitor = client->monitor;
|
||||||
|
set_pointer_position(current_monitor->pointer_x,
|
||||||
|
current_monitor->pointer_y);
|
||||||
current_monitor->selected_tags = client->tags;
|
current_monitor->selected_tags = client->tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
13
src/utils.c
13
src/utils.c
@@ -2,11 +2,14 @@
|
|||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
double get_time() {
|
double get_time() {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
@@ -105,11 +108,11 @@ void extract_color_channel(const uint32_t rgba, double *red, double *green,
|
|||||||
*alpha = COLOR_SPLIT(rgba, 0);
|
*alpha = COLOR_SPLIT(rgba, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INTERSECT(x, y, w, h, m) \
|
#define INTERSECT(x, y, w, h, m) \
|
||||||
(MAX(0, MIN((x) + (w), (m)->window_x + (m)->window_width) - \
|
(MAX(0, MIN((x) + (w), (m)->monitor_x + (int)(m)->monitor_width) - \
|
||||||
MAX((x), (m)->window_x)) * \
|
MAX((x), (m)->monitor_x)) * \
|
||||||
MAX(0, MIN((y) + (h), (m)->window_y + (m)->window_height) - \
|
MAX(0, MIN((y) + (h), (m)->monitor_y + (int)(m)->monitor_height) - \
|
||||||
MAX((y), (m)->window_y)))
|
MAX((y), (m)->monitor_y)))
|
||||||
monitor_t *rect_to_monitor(monitor_t *monitors, int32_t x, int32_t y,
|
monitor_t *rect_to_monitor(monitor_t *monitors, int32_t x, int32_t y,
|
||||||
uint32_t width, uint32_t height) {
|
uint32_t width, uint32_t height) {
|
||||||
monitor_t *r = monitors;
|
monitor_t *r = monitors;
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ static void convert_event(xcb_generic_event_t *xcb_event,
|
|||||||
event->motiion_notify.window = ev->event;
|
event->motiion_notify.window = ev->event;
|
||||||
event->motiion_notify.x = ev->event_x;
|
event->motiion_notify.x = ev->event_x;
|
||||||
event->motiion_notify.y = ev->event_y;
|
event->motiion_notify.y = ev->event_y;
|
||||||
|
event->motiion_notify.time = ev->time;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case XCB_ENTER_NOTIFY: {
|
case XCB_ENTER_NOTIFY: {
|
||||||
|
|||||||
@@ -337,6 +337,11 @@ bool get_pointer_position(int32_t *x, int32_t *y) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_pointer_position(int32_t x, int32_t y) {
|
||||||
|
xcb_warp_pointer(conn, XCB_WINDOW_NONE, screen->root, 0, 0, 1, 1, x, y);
|
||||||
|
xcb_flush(conn);
|
||||||
|
}
|
||||||
|
|
||||||
bool xcb_check_mask_event(xcb_event_mask_t event_mask) {
|
bool xcb_check_mask_event(xcb_event_mask_t event_mask) {
|
||||||
xcb_generic_event_t *event = xcb_poll_for_event(conn);
|
xcb_generic_event_t *event = xcb_poll_for_event(conn);
|
||||||
if (!event) return false;
|
if (!event) return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user