fix single key press detection

This commit is contained in:
nakst 2021-09-20 17:37:38 +01:00
parent 6c7ac5e749
commit 622073ffb2
5 changed files with 63 additions and 73 deletions

View File

@ -1,8 +1,6 @@
#include <essence.h>
#include <shared/strings.cpp>
// TODO Application icon.
#define TILE_COUNT (4)
#define TILE_SIZE ((int32_t) (75 * scale))
#define TILE_GAP ((int32_t) (10 * scale))

View File

@ -561,6 +561,30 @@ WindowTab *WindowTabMoveToNewContainer(WindowTab *tab, ContainerWindow *containe
return newTab;
}
int CursorLocatorMessage(EsElement *element, EsMessage *message) {
EsWindow *window = element->window;
if (message->type == ES_MSG_ANIMATE) {
window->announcementTimeMs += message->animate.deltaMs;
double progress = window->announcementTimeMs / GetConstantNumber("cursorLocatorDuration");
if (progress > 1) {
EsElementDestroy(window);
} else {
EsElementRelayout(element);
message->animate.complete = false;
return ES_HANDLED;
}
} else if (message->type == ES_MSG_LAYOUT) {
EsElement *child = element->GetChild(0);
double progress = 1.0 - window->announcementTimeMs / GetConstantNumber("cursorLocatorDuration");
int width = progress * child->GetWidth(0), height = progress * child->GetHeight(0);
child->InternalMove(width, height, (element->width - width) / 2, (element->height - height) / 2);
}
return 0;
}
int ProcessGlobalKeyboardShortcuts(EsElement *, EsMessage *message) {
if (desktop.installationState) {
// Do not process global keyboard shortcuts if the installer is running.
@ -580,6 +604,21 @@ int ProcessGlobalKeyboardShortcuts(EsElement *, EsMessage *message) {
}
return ES_HANDLED;
} else if (message->type == ES_MSG_KEY_UP) {
if (message->keyboard.scancode == ES_SCANCODE_LEFT_CTRL && message->keyboard.single) {
if (EsSystemConfigurationReadInteger(EsLiteral("general"), EsLiteral("locate_cursor_on_ctrl"))) {
EsPoint position = EsMouseGetPosition();
EsWindow *window = EsWindowCreate(nullptr, ES_WINDOW_TIP);
EsElement *wrapper = EsCustomElementCreate(window, ES_CELL_FILL, ES_STYLE_CLEAR_BACKGROUND);
wrapper->messageUser = CursorLocatorMessage;
window->announcementBase = position;
EsElement *element = EsCustomElementCreate(wrapper, ES_CELL_FILL, ES_STYLE_CURSOR_LOCATOR);
int width = element->GetWidth(0), height = element->GetHeight(0);
EsRectangle bounds = ES_RECT_4PD(position.x - width / 2, position.y - height / 2, width, height);
EsSyscall(ES_SYSCALL_WINDOW_MOVE, window->handle, (uintptr_t) &bounds, 0, ES_WINDOW_MOVE_ALWAYS_ON_TOP);
wrapper->StartAnimating();
}
}
}
return 0;
@ -651,6 +690,8 @@ int ContainerWindowMessage(EsElement *element, EsMessage *message) {
ProcessGlobalKeyboardShortcuts(element, message);
}
}
} else if (message->type == ES_MSG_KEY_UP) {
ProcessGlobalKeyboardShortcuts(element, message);
} else if (message->type == ES_MSG_WINDOW_RESIZED) {
container->tabBand->preventNextTabSizeAnimation = true;
}
@ -2720,30 +2761,6 @@ void EmbeddedWindowDestroyed(EsObjectID id) {
EsHeapFree(instance);
}
int CursorLocatorMessage(EsElement *element, EsMessage *message) {
EsWindow *window = element->window;
if (message->type == ES_MSG_ANIMATE) {
window->announcementTimeMs += message->animate.deltaMs;
double progress = window->announcementTimeMs / GetConstantNumber("cursorLocatorDuration");
if (progress > 1) {
EsElementDestroy(window);
} else {
EsElementRelayout(element);
message->animate.complete = false;
return ES_HANDLED;
}
} else if (message->type == ES_MSG_LAYOUT) {
EsElement *child = element->GetChild(0);
double progress = 1.0 - window->announcementTimeMs / GetConstantNumber("cursorLocatorDuration");
int width = progress * child->GetWidth(0), height = progress * child->GetHeight(0);
child->InternalMove(width, height, (element->width - width) / 2, (element->height - height) / 2);
}
return 0;
}
void DesktopMessage(EsMessage *message) {
if (message->type == ES_MSG_POWER_BUTTON_PRESSED) {
ShutdownModalCreate();
@ -2815,19 +2832,6 @@ void DesktopMessage(EsMessage *message) {
} else {
// The screen resolution will be correctly queried in DesktopSetup.
}
} else if (message->type == ES_MSG_SINGLE_CTRL_PRESS) {
if (EsSystemConfigurationReadInteger(EsLiteral("general"), EsLiteral("locate_cursor_on_ctrl"))) {
EsPoint position = EsMouseGetPosition();
EsWindow *window = EsWindowCreate(nullptr, ES_WINDOW_TIP);
EsElement *wrapper = EsCustomElementCreate(window, ES_CELL_FILL, ES_STYLE_CLEAR_BACKGROUND);
wrapper->messageUser = CursorLocatorMessage;
window->announcementBase = position;
EsElement *element = EsCustomElementCreate(wrapper, ES_CELL_FILL, ES_STYLE_CURSOR_LOCATOR);
int width = element->GetWidth(0), height = element->GetHeight(0);
EsRectangle bounds = ES_RECT_4PD(position.x - width / 2, position.y - height / 2, width, height);
EsSyscall(ES_SYSCALL_WINDOW_MOVE, window->handle, (uintptr_t) &bounds, 0, ES_WINDOW_MOVE_ALWAYS_ON_TOP);
wrapper->StartAnimating();
}
} else if (message->type == ES_MSG_INSTANCE_DESTROY) {
CommonDesktopInstance *instance = (CommonDesktopInstance *) message->instanceDestroy.instance;

View File

@ -45,7 +45,7 @@ struct {
bool menuMode;
// Access keys.
bool accessKeyMode, unhandledAltPress;
bool accessKeyMode, accessKeyModeJustExited;
struct {
Array<AccessKeyEntry> entries;
@ -6589,7 +6589,7 @@ void AccessKeyModeExit() {
}
void AccessKeyModeHandleKeyPress(EsMessage *message) {
if (message->type == ES_MSG_KEY_UP) {
if (message->type == ES_MSG_KEY_UP || message->keyboard.scancode == ES_SCANCODE_LEFT_ALT) {
return;
}
@ -6665,23 +6665,20 @@ bool UIHandleKeyMessage(EsWindow *window, EsMessage *message) {
if (message->keyboard.scancode == ES_SCANCODE_RIGHT_SHIFT) gui.rightModifiers &= ~ES_MODIFIER_SHIFT;
if (message->keyboard.scancode == ES_SCANCODE_RIGHT_FLAG ) gui.rightModifiers &= ~ES_MODIFIER_FLAG;
if (message->keyboard.scancode == ES_SCANCODE_LEFT_ALT && gui.unhandledAltPress) {
if (message->keyboard.scancode == ES_SCANCODE_LEFT_ALT && message->keyboard.single) {
AccessKeyModeEnter(window);
return true;
} else if (window->focused) {
EsMessageSend(window->focused, message);
return true;
return ES_HANDLED == EsMessageSend(window->focused, message);
} else {
return ES_HANDLED == EsMessageSend(window, message);
}
return false;
}
if (window->targetMenu) {
window = window->targetMenu;
}
gui.unhandledAltPress = false;
if (message->keyboard.scancode == ES_SCANCODE_F2 && message->keyboard.modifiers == ES_MODIFIER_ALT) {
EnterDebugger();
EsPrint("[Alt-F2]\n");
@ -6758,7 +6755,9 @@ bool UIHandleKeyMessage(EsWindow *window, EsMessage *message) {
return true;
}
} else {
EsMessageSend(window, message);
if (ES_HANDLED == EsMessageSend(window, message)) {
return true;
}
}
// TODO Radio group navigation.
@ -6776,11 +6775,6 @@ bool UIHandleKeyMessage(EsWindow *window, EsMessage *message) {
if (!window->hasDialog) {
// TODO Sort out what commands can be used from within dialogs and menus.
if (message->keyboard.scancode == ES_SCANCODE_LEFT_ALT) {
gui.unhandledAltPress = true;
return true;
}
if (!gui.keyboardShortcutNames.itemCount) UIInitialiseKeyboardShortcutNamesTable();
const char *shortcutName = (const char *) HashTableGetShort(&gui.keyboardShortcutNames, message->keyboard.scancode);

View File

@ -892,6 +892,7 @@ enum EsMessageType {
ES_MSG_KEY_DOWN = 0x100E // Propagates to ancestors if unhandled.
ES_MSG_KEY_UP = 0x100F
ES_MSG_UPDATE_WINDOW = 0x1010
ES_MSG_SINGLE_ALT_PRESS = 0x1011
ES_MSG_WM_END = 0x13FF
// Internal GUI messages: // None of these should be sent directly.
@ -968,7 +969,6 @@ enum EsMessageType {
ES_MSG_DESKTOP = 0x4806
ES_MSG_DEVICE_CONNECTED = 0x4807
ES_MSG_DEVICE_DISCONNECTED = 0x4808
ES_MSG_SINGLE_CTRL_PRESS = 0x4809
// Messages sent from Desktop to application instances:
ES_MSG_TAB_INSPECT_UI = 0x4A01
@ -1546,7 +1546,7 @@ struct EsMessageMouseButton {
struct EsMessageKeyboard {
uint32_t scancode;
uint8_t modifiers;
bool repeat, numpad, numlock;
bool repeat, numpad, numlock, single;
};
struct EsMessageAnimate {

View File

@ -115,6 +115,8 @@ struct WindowManager {
bool shift2, alt2, ctrl2, flag2;
bool numlock;
uint8_t modifiers;
uint16_t keysHeld, maximumKeysHeld /* cleared when all released */;
uint8_t keysHeldBitSet[512 / 8];
// Eyedropper:
@ -127,7 +129,6 @@ struct WindowManager {
// Miscellaneous:
EsRectangle workArea;
bool inSingleCtrlPress;
// Game controllers:
@ -285,16 +286,10 @@ void WindowManager::PressKey(unsigned scancode) {
KernelPanic("WindowManager::PressKey - Panic key pressed.\n");
}
if (scancode == ES_SCANCODE_LEFT_CTRL) {
inSingleCtrlPress = true;
} else if (scancode == (ES_SCANCODE_LEFT_CTRL | K_SCANCODE_KEY_RELEASED) && inSingleCtrlPress) {
EsMessage m;
EsMemoryZero(&m, sizeof(EsMessage));
m.type = ES_MSG_SINGLE_CTRL_PRESS;
desktopProcess->messageQueue.SendMessage(nullptr, &m);
} else {
inSingleCtrlPress = false;
}
bool single = (scancode & K_SCANCODE_KEY_RELEASED) && maximumKeysHeld == 1;
keysHeld += (scancode & K_SCANCODE_KEY_RELEASED) ? -1 : 1;
keysHeld = MaximumInteger(keysHeld, 0); // Prevent negative keys held count.
maximumKeysHeld = (!keysHeld || keysHeld > maximumKeysHeld) ? keysHeld : maximumKeysHeld;
if (eyedropping) {
if (scancode == (ES_SCANCODE_ESCAPE | K_SCANCODE_KEY_RELEASED)) {
@ -337,21 +332,20 @@ void WindowManager::PressKey(unsigned scancode) {
message.keyboard.modifiers = modifiers;
message.keyboard.scancode = scancode & ~K_SCANCODE_KEY_RELEASED;
message.keyboard.numlock = numlock;
static uint8_t heldKeys[512 / 8] = {};
message.keyboard.single = single;
if (message.keyboard.scancode >= 512) {
KernelPanic("WindowManager::PressKey - Scancode outside valid range.\n");
}
if (message.type == ES_MSG_KEY_DOWN && (heldKeys[message.keyboard.scancode / 8] & (1 << (message.keyboard.scancode % 8)))) {
if (message.type == ES_MSG_KEY_DOWN && (keysHeldBitSet[message.keyboard.scancode / 8] & (1 << (message.keyboard.scancode % 8)))) {
message.keyboard.repeat = true;
}
if (message.type == ES_MSG_KEY_DOWN) {
heldKeys[message.keyboard.scancode / 8] |= (1 << (message.keyboard.scancode % 8));
keysHeldBitSet[message.keyboard.scancode / 8] |= (1 << (message.keyboard.scancode % 8));
} else {
heldKeys[message.keyboard.scancode / 8] &= ~(1 << (message.keyboard.scancode % 8));
keysHeldBitSet[message.keyboard.scancode / 8] &= ~(1 << (message.keyboard.scancode % 8));
}
if (activeWindow) {