From 017e6fe13e17e3590c763f555a8d027254c97e57 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sat, 11 May 2024 15:21:48 +0000 Subject: [PATCH] Fix display(8) windows receiving handled keystrokes. --- display/display-code.c | 27 ++++++++++-------- display/display.h | 1 + display/window.c | 62 +++++++++++++++++++++++++++++++++++++++++- display/window.h | 3 ++ 4 files changed, 80 insertions(+), 13 deletions(-) diff --git a/display/display-code.c b/display/display-code.c index ddd149fc..fbe3666f 100644 --- a/display/display-code.c +++ b/display/display-code.c @@ -160,6 +160,7 @@ void display_unmark_active_window(struct display* display, window->focus = false; display->active_window = NULL; window_render_frame(window); + window_unsend_keys(window); } void display_mark_active_window(struct display* display, struct window* window) @@ -466,6 +467,11 @@ void display_keyboard_event(struct display* display, uint32_t codepoint) int kbkey = KBKEY_DECODE(codepoint); int abskbkey = kbkey < 0 ? -kbkey : kbkey; + if ( !kbkey && display->codepoint_discard ) + return; + else if ( kbkey < 0 ) + display->codepoint_discard = false; + if ( kbkey && (!window || !window->grab_input) ) { switch ( abskbkey ) @@ -484,6 +490,7 @@ void display_keyboard_event(struct display* display, uint32_t codepoint) execlp("terminal", "terminal", (char*) NULL); _exit(127); } + display->codepoint_discard = true; return; } else if ( display->key_lctrl && display->key_lalt && kbkey == -KBKEY_T ) @@ -496,18 +503,21 @@ void display_keyboard_event(struct display* display, uint32_t codepoint) if ( (display->key_lalt && kbkey == KBKEY_F4) /* || (display->key_lctrl && kbkey == KBKEY_Q)*/ ) { + display->codepoint_discard = true; window_quit(window); return; } if ( display->key_lalt && kbkey == KBKEY_F10 ) { + display->codepoint_discard = true; window_toggle_maximized(display->active_window); return; } if ( display->key_lalt && kbkey == KBKEY_TAB ) { + display->codepoint_discard = true; if ( !display->tab_candidate ) display->tab_candidate = display->active_window; struct window* old_candidate = display->tab_candidate; @@ -531,21 +541,25 @@ void display_keyboard_event(struct display* display, uint32_t codepoint) struct window* window = display->active_window; if ( kbkey == KBKEY_LEFT ) { + display->codepoint_discard = true; window_tile_leftward(window); return; } if ( kbkey == KBKEY_RIGHT ) { + display->codepoint_discard = true; window_tile_rightward(window); return; } if ( kbkey == KBKEY_UP ) { + display->codepoint_discard = true; window_tile_up(window); return; } if ( kbkey == KBKEY_DOWN ) { + display->codepoint_discard = true; window_tile_down(window); return; } @@ -580,18 +594,7 @@ void display_keyboard_event(struct display* display, uint32_t codepoint) if ( !window ) return; - struct event_keyboard event; - event.window_id = display->active_window->window_id; - event.codepoint = codepoint; - - struct display_packet_header header; - header.id = EVENT_KEYBOARD; - header.size = sizeof(event); - - assert(window->connection); - - connection_schedule_transmit(window->connection, &header, sizeof(header)); - connection_schedule_transmit(window->connection, &event, sizeof(event)); + window_send_key(display->active_window, codepoint); } void display_mouse_event(struct display* display, uint8_t byte) diff --git a/display/display.h b/display/display.h index bac429d6..a8635344 100644 --- a/display/display.h +++ b/display/display.h @@ -66,6 +66,7 @@ struct display bool key_lalt; bool key_lsuper; bool key_rsuper; + bool codepoint_discard; bool redraw; int pointer_x; int pointer_y; diff --git a/display/window.c b/display/window.c index 51f9065c..1ebdc765 100644 --- a/display/window.c +++ b/display/window.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, 2016, 2017, 2022, 2023 Jonas 'Sortie' Termansen. + * Copyright (c) 2014-2017, 2022-2024 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,6 +17,8 @@ * Window abstraction. */ +#include + #include #include #include @@ -573,3 +575,61 @@ void window_notify_client_resize(struct window* window) connection_schedule_transmit(window->connection, &header, sizeof(header)); connection_schedule_transmit(window->connection, &event, sizeof(event)); } + +void window_send_key(struct window* window, uint32_t codepoint) +{ + int kbkey = KBKEY_DECODE(codepoint); + unsigned int abskbkey = kbkey < 0 ? -kbkey : kbkey; + if ( 0 < abskbkey && abskbkey < 512 ) + { + size_t index = abskbkey / (8 * sizeof(size_t)); + size_t bit = abskbkey % (8 * sizeof(size_t)); + size_t mask = 1ULL << bit; + if ( kbkey < 0 ) + window->key_bitmap[index] &= ~mask; + else + window->key_bitmap[index] |= mask; + } + + struct event_keyboard event; + event.window_id = window->window_id; + event.codepoint = codepoint; + + struct display_packet_header header; + header.id = EVENT_KEYBOARD; + header.size = sizeof(event); + + assert(window->connection); + + connection_schedule_transmit(window->connection, &header, sizeof(header)); + connection_schedule_transmit(window->connection, &event, sizeof(event)); +} + +void window_unsend_keys(struct window* window) +{ + struct event_keyboard event; + event.window_id = window->window_id; + event.codepoint = 0; + + struct display_packet_header header; + header.id = EVENT_KEYBOARD; + header.size = sizeof(event); + + assert(window->connection); + + for ( int kbkey = 1; kbkey < 512; kbkey++ ) + { + size_t index = kbkey / (8 * sizeof(size_t)); + size_t bit = kbkey % (8 * sizeof(size_t)); + size_t mask = 1ULL << bit; + if ( window->key_bitmap[index] & mask ) + { + event.codepoint = KBKEY_ENCODE(-kbkey); + connection_schedule_transmit(window->connection, &header, + sizeof(header)); + connection_schedule_transmit(window->connection, &event, + sizeof(event)); + } + } + memset(window->key_bitmap, 0, sizeof(window->key_bitmap)); +} diff --git a/display/window.h b/display/window.h index 58f93e84..a0216f0a 100644 --- a/display/window.h +++ b/display/window.h @@ -81,6 +81,7 @@ struct window bool show; bool focus; bool grab_input; + size_t key_bitmap[512 / (8 * sizeof(size_t))]; }; struct framebuffer window_client_buffer(struct window* window); @@ -115,5 +116,7 @@ void window_tile_bottom(struct window* window); void window_tile_bottom_left(struct window* window); void window_tile_bottom_right(struct window* window); void window_notify_client_resize(struct window* window); +void window_send_key(struct window* window, uint32_t codepoint); +void window_unsend_keys(struct window* window); #endif