处理移动鼠标事件
This commit is contained in:
@@ -71,6 +71,12 @@ typedef struct expose_event_t {
|
||||
|
||||
typedef struct motion_notify_event_t {
|
||||
event_type_t type;
|
||||
xcb_window_t root;
|
||||
int32_t root_x;
|
||||
int32_t root_y;
|
||||
xcb_window_t window;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
} motion_notify_event_t;
|
||||
|
||||
typedef struct enter_notify_event_t {
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define LENGTH(X) (sizeof(X) / sizeof(X)[0])
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
@@ -40,3 +42,6 @@ uint32_t rgba_to_argb(uint32_t rgba);
|
||||
*/
|
||||
void extract_color_channel(const uint32_t rgba, double *red, double *green,
|
||||
double *blue, double *alpha);
|
||||
|
||||
monitor_t *rect_to_monitor(monitor_t *monitors, int32_t x, int32_t y,
|
||||
uint32_t width, uint32_t height);
|
||||
|
||||
28
src/main.c
28
src/main.c
@@ -39,6 +39,7 @@ static void key_press(key_press_event_t *event);
|
||||
static void configure_request(configure_request_event_t *event);
|
||||
static void map_request(map_request_event_t *event);
|
||||
static void unmap_notify(unmap_notify_event_t *event);
|
||||
static void motion_notify(motion_notify_event_t *event);
|
||||
static void manage_window(xcb_window_t window);
|
||||
static void unmanage_client(client_t *client);
|
||||
static void update_client_name(client_t *client);
|
||||
@@ -52,6 +53,7 @@ static void arrange(monitor_t *monitor);
|
||||
static void show_hide_client(client_t *client);
|
||||
static void restack(monitor_t *monitor);
|
||||
static void focus(client_t *client);
|
||||
static void unfocus(client_t *client, bool set_focus);
|
||||
static void apply_monitor_layout(monitor_t *monitor);
|
||||
static client_t *get_client_of_window(xcb_window_t window);
|
||||
static gboolean handle_xcb_event(GIOChannel *channel, GIOCondition condition,
|
||||
@@ -457,6 +459,7 @@ void xcb_event_handler(generic_event_t *event, void *user_data) {
|
||||
EVENT(EVENT_TYPE_CONFIGURE_REQUEST, configure_request);
|
||||
EVENT(EVENT_TYPE_MAP_REQUEST, map_request);
|
||||
EVENT(EVENT_TYPE_UNMAP_NOTIFY, unmap_notify);
|
||||
EVENT(EVENT_TYPE_MOTION_NOTIFY, motion_notify);
|
||||
|
||||
#undef EVENT
|
||||
|
||||
@@ -505,6 +508,19 @@ void unmap_notify(unmap_notify_event_t *event) {
|
||||
}
|
||||
}
|
||||
|
||||
void motion_notify(motion_notify_event_t *event) {
|
||||
if (event->window != get_root_window()) return;
|
||||
|
||||
static monitor_t *mon = NULL;
|
||||
monitor_t *m = rect_to_monitor(monitors, event->root_x, event->root_y, 1, 1);
|
||||
if (mon && m != mon) {
|
||||
unfocus(current_monitor->selected_client, true);
|
||||
current_monitor = m;
|
||||
focus(NULL);
|
||||
}
|
||||
mon = m;
|
||||
}
|
||||
|
||||
void manage_window(xcb_window_t window) {
|
||||
window_geometry_t *geometry = get_window_geometry(window);
|
||||
client_t *c = ecalloc(1, sizeof(client_t));
|
||||
@@ -660,12 +676,22 @@ void arrange(monitor_t *monitor) {
|
||||
}
|
||||
}
|
||||
|
||||
void restack(monitor_t *monitor) { /* TODO: */ draw_monitor_bar(monitor); }
|
||||
void restack(monitor_t *monitor) {
|
||||
draw_monitor_bar(monitor);
|
||||
/* TODO: */
|
||||
}
|
||||
void focus(client_t *client) {
|
||||
/* TODO: */
|
||||
current_monitor->selected_client = client;
|
||||
draw_all_monitor_bars();
|
||||
}
|
||||
void unfocus(client_t *client, bool set_focus) {
|
||||
if (!client) return;
|
||||
change_window_border_color(client->window, color_set->border_color.argb);
|
||||
if (set_focus) {
|
||||
/* TODO: */
|
||||
}
|
||||
}
|
||||
|
||||
void show_hide_client(client_t *client) {
|
||||
if (!client) return;
|
||||
|
||||
19
src/utils.c
19
src/utils.c
@@ -93,3 +93,22 @@ void extract_color_channel(const uint32_t rgba, double *red, double *green,
|
||||
*blue = COLOR_SPLIT(rgba, 8);
|
||||
*alpha = COLOR_SPLIT(rgba, 0);
|
||||
}
|
||||
|
||||
#define INTERSECT(x, y, w, h, m) \
|
||||
(MAX(0, MIN((x) + (w), (m)->window_x + (m)->window_width) - \
|
||||
MAX((x), (m)->window_x)) * \
|
||||
MAX(0, MIN((y) + (h), (m)->window_y + (m)->window_height) - \
|
||||
MAX((y), (m)->window_y)))
|
||||
monitor_t *rect_to_monitor(monitor_t *monitors, int32_t x, int32_t y,
|
||||
uint32_t width, uint32_t height) {
|
||||
monitor_t *r = monitors;
|
||||
int32_t a, area = 0;
|
||||
for (monitor_t *m = monitors; m; m = m->next) {
|
||||
if ((a = INTERSECT(x, y, width, height, m)) > area) {
|
||||
area = a;
|
||||
r = m;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -73,9 +73,17 @@ static void convert_event(xcb_generic_event_t *xcb_event,
|
||||
case XCB_EXPOSE:
|
||||
event->type = EVENT_TYPE_EXPOSE;
|
||||
break;
|
||||
case XCB_MOTION_NOTIFY:
|
||||
event->type = EVENT_TYPE_MOTION_NOTIFY;
|
||||
case XCB_MOTION_NOTIFY: {
|
||||
xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)xcb_event;
|
||||
event->motiion_notify.type = EVENT_TYPE_MOTION_NOTIFY;
|
||||
event->motiion_notify.root = ev->root;
|
||||
event->motiion_notify.root_x = ev->root_x;
|
||||
event->motiion_notify.root_y = ev->root_y;
|
||||
event->motiion_notify.window = ev->event;
|
||||
event->motiion_notify.x = ev->event_x;
|
||||
event->motiion_notify.y = ev->event_y;
|
||||
break;
|
||||
}
|
||||
case XCB_ENTER_NOTIFY:
|
||||
event->type = EVENT_TYPE_ENTER_NOTIFY;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user