Fix display(8) windows receiving handled keystrokes.

This commit is contained in:
Jonas 'Sortie' Termansen 2024-05-11 15:21:48 +00:00
parent 9c5ea68951
commit 017e6fe13e
4 changed files with 80 additions and 13 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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 <sys/keycodes.h>
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
@ -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));
}

View File

@ -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