yutani: track keyboard modifiers with mouse events

This commit is contained in:
K. Lange 2018-12-07 11:05:21 +09:00
parent 3fa34ab7d0
commit 20f3d83e92
7 changed files with 43 additions and 21 deletions

View File

@ -1433,6 +1433,7 @@ static void window_untile(yutani_globals_t * yg, yutani_server_window_t * window
* We also process key bindings for other applications.
*/
static void handle_key_event(yutani_globals_t * yg, struct yutani_msg_key_event * ke) {
yg->active_modifiers = ke->event.modifiers;
yutani_server_window_t * focused = get_focused(yg);
memcpy(&yg->kbd_state, &ke->state, sizeof(key_event_state_t));
if (focused) {
@ -1789,7 +1790,7 @@ static void handle_mouse_event(yutani_globals_t * yg, struct yutani_msg_mouse_ev
if (yg->mouse_window) {
yutani_device_to_window(yg->mouse_window, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE, &yg->mouse_click_x, &yg->mouse_click_y);
yutani_msg_buildx_window_mouse_event_alloc(response);
yutani_msg_buildx_window_mouse_event(response,yg->mouse_window->wid, yg->mouse_click_x, yg->mouse_click_y, -1, -1, me->event.buttons, YUTANI_MOUSE_EVENT_DOWN);
yutani_msg_buildx_window_mouse_event(response,yg->mouse_window->wid, yg->mouse_click_x, yg->mouse_click_y, -1, -1, me->event.buttons, YUTANI_MOUSE_EVENT_DOWN, yg->active_modifiers);
yg->mouse_click_x_orig = yg->mouse_click_x;
yg->mouse_click_y_orig = yg->mouse_click_y;
pex_send(yg->server, yg->mouse_window->owner, response->size, (char *)response);
@ -1801,7 +1802,7 @@ static void handle_mouse_event(yutani_globals_t * yg, struct yutani_msg_mouse_ev
int32_t x, y;
yutani_device_to_window(yg->mouse_window, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE, &x, &y);
yutani_msg_buildx_window_mouse_event_alloc(response);
yutani_msg_buildx_window_mouse_event(response,yg->mouse_window->wid, x, y, -1, -1, me->event.buttons, YUTANI_MOUSE_EVENT_MOVE);
yutani_msg_buildx_window_mouse_event(response,yg->mouse_window->wid, x, y, -1, -1, me->event.buttons, YUTANI_MOUSE_EVENT_MOVE, yg->active_modifiers);
pex_send(yg->server, yg->mouse_window->owner, response->size, (char *)response);
}
if (tmp_window) {
@ -1809,18 +1810,18 @@ static void handle_mouse_event(yutani_globals_t * yg, struct yutani_msg_mouse_ev
yutani_msg_buildx_window_mouse_event_alloc(response);
if (tmp_window != yg->old_hover_window) {
yutani_device_to_window(tmp_window, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE, &x, &y);
yutani_msg_buildx_window_mouse_event(response, tmp_window->wid, x, y, -1, -1, me->event.buttons, YUTANI_MOUSE_EVENT_ENTER);
yutani_msg_buildx_window_mouse_event(response, tmp_window->wid, x, y, -1, -1, me->event.buttons, YUTANI_MOUSE_EVENT_ENTER, yg->active_modifiers);
pex_send(yg->server, tmp_window->owner, response->size, (char *)response);
if (yg->old_hover_window) {
yutani_device_to_window(yg->old_hover_window, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE, &x, &y);
yutani_msg_buildx_window_mouse_event(response, yg->old_hover_window->wid, x, y, -1, -1, me->event.buttons, YUTANI_MOUSE_EVENT_LEAVE);
yutani_msg_buildx_window_mouse_event(response, yg->old_hover_window->wid, x, y, -1, -1, me->event.buttons, YUTANI_MOUSE_EVENT_LEAVE, yg->active_modifiers);
pex_send(yg->server, yg->old_hover_window->owner, response->size, (char *)response);
}
yg->old_hover_window = tmp_window;
}
if (tmp_window != yg->mouse_window || (me->event.buttons & YUTANI_MOUSE_BUTTON_RIGHT)) {
yutani_device_to_window(tmp_window, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE, &x, &y);
yutani_msg_buildx_window_mouse_event(response, tmp_window->wid, x, y, -1, -1, me->event.buttons, YUTANI_MOUSE_EVENT_MOVE);
yutani_msg_buildx_window_mouse_event(response, tmp_window->wid, x, y, -1, -1, me->event.buttons, YUTANI_MOUSE_EVENT_MOVE, yg->active_modifiers);
pex_send(yg->server, tmp_window->owner, response->size, (char *)response);
}
}
@ -1906,11 +1907,11 @@ static void handle_mouse_event(yutani_globals_t * yg, struct yutani_msg_mouse_ev
yutani_device_to_window(yg->mouse_window, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE, &yg->mouse_click_x, &yg->mouse_click_y);
if (!yg->mouse_moved) {
yutani_msg_buildx_window_mouse_event_alloc(response);
yutani_msg_buildx_window_mouse_event(response,yg->mouse_window->wid, yg->mouse_click_x, yg->mouse_click_y, -1, -1, me->event.buttons, YUTANI_MOUSE_EVENT_CLICK);
yutani_msg_buildx_window_mouse_event(response,yg->mouse_window->wid, yg->mouse_click_x, yg->mouse_click_y, -1, -1, me->event.buttons, YUTANI_MOUSE_EVENT_CLICK, yg->active_modifiers);
pex_send(yg->server, yg->mouse_window->owner, response->size, (char *)response);
} else {
yutani_msg_buildx_window_mouse_event_alloc(response);
yutani_msg_buildx_window_mouse_event(response,yg->mouse_window->wid, yg->mouse_click_x, yg->mouse_click_y, old_x, old_y, me->event.buttons, YUTANI_MOUSE_EVENT_RAISE);
yutani_msg_buildx_window_mouse_event(response,yg->mouse_window->wid, yg->mouse_click_x, yg->mouse_click_y, old_x, old_y, me->event.buttons, YUTANI_MOUSE_EVENT_RAISE, yg->active_modifiers);
pex_send(yg->server, yg->mouse_window->owner, response->size, (char *)response);
}
}
@ -1923,7 +1924,7 @@ static void handle_mouse_event(yutani_globals_t * yg, struct yutani_msg_mouse_ev
yutani_device_to_window(yg->mouse_window, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE, &yg->mouse_click_x, &yg->mouse_click_y);
if (old_x != yg->mouse_click_x || old_y != yg->mouse_click_y) {
yutani_msg_buildx_window_mouse_event_alloc(response);
yutani_msg_buildx_window_mouse_event(response,yg->mouse_window->wid, yg->mouse_click_x, yg->mouse_click_y, old_x, old_y, me->event.buttons, YUTANI_MOUSE_EVENT_DRAG);
yutani_msg_buildx_window_mouse_event(response,yg->mouse_window->wid, yg->mouse_click_x, yg->mouse_click_y, old_x, old_y, me->event.buttons, YUTANI_MOUSE_EVENT_DRAG, yg->active_modifiers);
pex_send(yg->server, yg->mouse_window->owner, response->size, (char *)response);
}
}

View File

@ -72,7 +72,6 @@ static struct File ** file_pointers = NULL; /* List of file pointers */
static ssize_t file_pointers_len = 0; /* How many files are in the current list */
static uint64_t last_click = 0; /* For double click */
static int last_click_offset = -1; /* So that clicking two different things quickly doesn't count as a double click */
static int modifiers = 0; /* For ctrl-click */
static int _button_hilights[4] = {3,3,3,3};
static int _button_disabled[4] = {1,1,0,0};
@ -1001,7 +1000,7 @@ static void toggle_selected(int hilighted_offset, int modifiers) {
f->selected = !f->selected;
/* If Ctrl wasn't held, unselect everything else. */
if (!(modifiers & KEY_MOD_LEFT_CTRL)) {
if (!(modifiers & YUTANI_KEY_MODIFIER_CTRL)) {
for (int i = 0; i < file_pointers_len; ++i) {
if (file_pointers[i] != f && file_pointers[i]->selected) {
file_pointers[i]->selected = 0;
@ -1232,7 +1231,6 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_KEY_EVENT:
{
struct yutani_msg_key_event * ke = (void*)m->data;
modifiers = ke->event.modifiers;
if (!is_desktop_background) {
if (ke->event.action == KEY_ACTION_DOWN && ke->event.keycode == 'q') {
_menu_action_exit(NULL);
@ -1405,10 +1403,10 @@ int main(int argc, char * argv[]) {
} else {
last_click = precise_current_time();
last_click_offset = hilighted_offset;
toggle_selected(hilighted_offset, modifiers);
toggle_selected(hilighted_offset, me->modifiers);
}
} else {
if (!(modifiers & KEY_MOD_LEFT_CTRL)) {
if (!(me->modifiers & YUTANI_KEY_MODIFIER_CTRL)) {
for (int i = 0; i < file_pointers_len; ++i) {
if (file_pointers[i]->selected) {
file_pointers[i]->selected = 0;
@ -1423,7 +1421,7 @@ int main(int argc, char * argv[]) {
if (!context_menu->window) {
struct File * f = get_file_at_offset(hilighted_offset);
if (f && !f->selected) {
toggle_selected(hilighted_offset, modifiers);
toggle_selected(hilighted_offset, me->modifiers);
}
menu_show(context_menu, main_window->ctx);
yutani_window_move(main_window->ctx, context_menu->window, me->new_x + main_window->x, me->new_y + main_window->y);

View File

@ -38,7 +38,6 @@ static int scroll_offset = 0; /* How far the icon view should be scrolled */
static int hilighted_offset = -1; /* Which file is hovered by the mouse */
static uint64_t last_click = 0; /* For double click */
static int last_click_offset = -1; /* So that clicking two different things quickly doesn't count as a double click */
static int modifiers = 0; /* For ctrl-click */
struct Package {
char name[256];
@ -446,7 +445,6 @@ int main(int argc, char * argv[]) {
case YUTANI_MSG_KEY_EVENT:
{
struct yutani_msg_key_event * ke = (void*)m->data;
modifiers = ke->event.modifiers;
if (ke->event.action == KEY_ACTION_DOWN && ke->event.keycode == 'q') {
_menu_action_exit(NULL);
}
@ -549,10 +547,10 @@ int main(int argc, char * argv[]) {
} else {
last_click = precise_current_time();
last_click_offset = hilighted_offset;
toggle_selected(hilighted_offset, modifiers);
toggle_selected(hilighted_offset, me->modifiers);
}
} else {
if (!(modifiers & KEY_MOD_LEFT_CTRL)) {
if (!(me->modifiers & YUTANI_KEY_MODIFIER_CTRL)) {
for (int i = 0; i < pkg_pointers_len; ++i) {
if (pkg_pointers[i]->selected) {
pkg_pointers[i]->selected = 0;
@ -568,7 +566,7 @@ int main(int argc, char * argv[]) {
if (!context_menu->window) {
struct Package * f = get_package_at_offset(hilighted_offset);
if (f && !f->selected) {
toggle_selected(hilighted_offset, modifiers);
toggle_selected(hilighted_offset, me->modifiers);
}
menu_show(context_menu, main_window->ctx);
yutani_window_move(main_window->ctx, context_menu->window, me->new_x + main_window->x, me->new_y + main_window->y);

View File

@ -51,7 +51,7 @@ extern void yutani_msg_buildx_mouse_event(yutani_msg_t * msg, yutani_wid_t wid,
extern void yutani_msg_buildx_window_move(yutani_msg_t * msg, yutani_wid_t wid, int32_t x, int32_t y);
extern void yutani_msg_buildx_window_stack(yutani_msg_t * msg, yutani_wid_t wid, int z);
extern void yutani_msg_buildx_window_focus_change(yutani_msg_t * msg, yutani_wid_t wid, int focused);
extern void yutani_msg_buildx_window_mouse_event(yutani_msg_t * msg, yutani_wid_t wid, int32_t new_x, int32_t new_y, int32_t old_x, int32_t old_y, uint8_t buttons, uint8_t command);
extern void yutani_msg_buildx_window_mouse_event(yutani_msg_t * msg, yutani_wid_t wid, int32_t new_x, int32_t new_y, int32_t old_x, int32_t old_y, uint8_t buttons, uint8_t command, uint8_t modifiers);
extern void yutani_msg_buildx_flip_region(yutani_msg_t * msg, yutani_wid_t wid, int32_t x, int32_t y, int32_t width, int32_t height);
extern void yutani_msg_buildx_window_resize(yutani_msg_t * msg, uint32_t type, yutani_wid_t wid, uint32_t width, uint32_t height, uint32_t bufid, uint32_t flags);
extern void yutani_msg_buildx_window_advertise(yutani_msg_t * msg, yutani_wid_t wid, uint32_t flags, uint16_t * offsets, size_t length, char * data);

View File

@ -287,6 +287,7 @@ typedef struct YutaniGlobals {
void * renderer_ctx;
int reload_renderer;
uint8_t active_modifiers;
} yutani_globals_t;
struct key_bind {

View File

@ -149,6 +149,7 @@ struct yutani_msg_window_mouse_event {
int32_t old_y;
uint8_t buttons;
uint8_t command;
uint8_t modifiers;
};
struct yutani_msg_mouse_event {
@ -366,6 +367,28 @@ struct yutani_msg_clipboard {
#define YUTANI_MOUSE_EVENT_TYPE_RELATIVE 0
#define YUTANI_MOUSE_EVENT_TYPE_ABSOLUTE 1
/*
* YUTANI_KEY_MODIFIER
*
* These are sent with mouse events. The LEFT and RIGHT
* version are specific to those keys. The non-LEFT/RIGHT
* versions are masks that can match either key.
*
* Must match with the <toaru/kbd.h> definitions.
*/
#define YUTANI_KEY_MODIFIER_LEFT_CTRL 0x01
#define YUTANI_KEY_MODIFIER_LEFT_SHIFT 0x02
#define YUTANI_KEY_MODIFIER_LEFT_ALT 0x04
#define YUTANI_KEY_MODIFIER_LEFT_SUPER 0x08
#define YUTANI_KEY_MODIFIER_RIGHT_CTRL 0x10
#define YUTANI_KEY_MODIFIER_RIGHT_SHIFT 0x40
#define YUTANI_KEY_MODIFIER_RIGHT_ALT 0x40
#define YUTANI_KEY_MODIFIER_RIGHT_SUPER 0x80
#define YUTANI_KEY_MODIFIER_CTRL 0x11
#define YUTANI_KEY_MODIFIER_SHIFT 0x22
#define YUTANI_KEY_MODIFIER_ALT 0x44
#define YUTANI_KEY_MODIFIER_SUPER 0x88
/*
* YUTANI_BIND
*

View File

@ -290,7 +290,7 @@ void yutani_msg_buildx_window_focus_change(yutani_msg_t * msg, yutani_wid_t wid,
}
void yutani_msg_buildx_window_mouse_event(yutani_msg_t * msg, yutani_wid_t wid, int32_t new_x, int32_t new_y, int32_t old_x, int32_t old_y, uint8_t buttons, uint8_t command) {
void yutani_msg_buildx_window_mouse_event(yutani_msg_t * msg, yutani_wid_t wid, int32_t new_x, int32_t new_y, int32_t old_x, int32_t old_y, uint8_t buttons, uint8_t command, uint8_t modifiers) {
msg->magic = YUTANI_MSG__MAGIC;
msg->type = YUTANI_MSG_WINDOW_MOUSE_EVENT;
msg->size = sizeof(struct yutani_message) + sizeof(struct yutani_msg_window_mouse_event);
@ -304,6 +304,7 @@ void yutani_msg_buildx_window_mouse_event(yutani_msg_t * msg, yutani_wid_t wid,
mw->old_y = old_y;
mw->buttons = buttons;
mw->command = command;
mw->modifiers = modifiers;
}