mirror of https://gitlab.com/nakst/essence
fix single key press detection
This commit is contained in:
parent
6c7ac5e749
commit
622073ffb2
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue