mirror of https://gitlab.com/nakst/essence
scroll wheel support
This commit is contained in:
parent
b096bc23c4
commit
125cdfde4b
|
@ -55,7 +55,6 @@ struct EnumString { const char *cName; int value; };
|
|||
#define DESKTOP_MSG_CLIPBOARD_GET (12)
|
||||
#define DESKTOP_MSG_SYSTEM_CONFIGURATION_GET (13)
|
||||
#define DESKTOP_MSG_FILE_TYPES_GET (14)
|
||||
#define DESKTOP_MSG_UNHANDLED_KEY_EVENT (15)
|
||||
#define DESKTOP_MSG_START_USER_TASK (16)
|
||||
#define DESKTOP_MSG_SET_PROGRESS (17)
|
||||
#define DESKTOP_MSG_RENAME (18)
|
||||
|
|
|
@ -2754,13 +2754,6 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) {
|
|||
desktop.installedApplications.Add(application);
|
||||
ApplicationInstanceCreate(application->id, nullptr, nullptr);
|
||||
}
|
||||
} else if (buffer[0] == DESKTOP_MSG_UNHANDLED_KEY_EVENT && instance->tab) {
|
||||
_EsMessageWithObject message;
|
||||
EsSyscall(ES_SYSCALL_WINDOW_GET_EMBED_KEYBOARD, instance->tab->window->handle, (uintptr_t) &message, 0, 0);
|
||||
|
||||
if (message.message.type != ES_MSG_INVALID) {
|
||||
UIProcessWindowManagerMessage((EsWindow *) message.object, &message.message, nullptr);
|
||||
}
|
||||
} else {
|
||||
EsPrint("DesktopSyscall - Received unhandled message %d.\n", buffer[0]);
|
||||
}
|
||||
|
|
|
@ -2858,6 +2858,9 @@ void ScrollPane::ReceivedMessage(EsMessage *message) {
|
|||
EsMessageSend(parent, &m);
|
||||
parent->internalOffsetRight = (m.measure.height + fixedViewport[1] > message->measure.height) ? bar[1]->currentStyle->preferredWidth : 0;
|
||||
}
|
||||
} else if (message->type == ES_MSG_SCROLL_WHEEL) {
|
||||
SetPosition(0, position[0] + message->scrollWheel.dx, true);
|
||||
SetPosition(1, position[1] + message->scrollWheel.dy, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7212,10 +7215,14 @@ void UIProcessWindowManagerMessage(EsWindow *window, EsMessage *message, Process
|
|||
goto doneInputMessage;
|
||||
}
|
||||
}
|
||||
} else if (message->type == ES_MSG_SCROLL_WHEEL) {
|
||||
EsElement *element = window->dragged ?: window->pressed ?: window->hovered;
|
||||
|
||||
if (window->windowStyle == ES_WINDOW_NORMAL) {
|
||||
uint8_t m = DESKTOP_MSG_UNHANDLED_KEY_EVENT;
|
||||
MessageDesktop(&m, 1, window->handle);
|
||||
message->scrollWheel.dx /= 5;
|
||||
message->scrollWheel.dy /= -5;
|
||||
|
||||
if (element && (~element->flags & ES_ELEMENT_DISABLED) && (~element->state & UI_STATE_BLOCK_INTERACTION)) {
|
||||
UIMessageSendPropagateToAncestors(element, message);
|
||||
}
|
||||
} else if (message->type == ES_MSG_WINDOW_RESIZED) {
|
||||
AccessKeyModeExit();
|
||||
|
|
|
@ -735,6 +735,8 @@ define ES_PATH_MOVE_ALLOW_COPY_AND_DELETE (1 << 0) // Copy and delete the file i
|
|||
|
||||
define ES_CLIPBOARD_ADD_LAZY_CUT (1 << 0) // Only perform the deletion after pasting; often implemented as a move.
|
||||
|
||||
define ES_SCROLL_WHEEL_SCALE (0x100)
|
||||
|
||||
include desktop/icons.header
|
||||
|
||||
enum EsFatalError {
|
||||
|
@ -814,7 +816,6 @@ enum EsSyscallType {
|
|||
ES_SYSCALL_WINDOW_FIND_BY_POINT
|
||||
ES_SYSCALL_WINDOW_GET_ID
|
||||
ES_SYSCALL_WINDOW_GET_BOUNDS
|
||||
ES_SYSCALL_WINDOW_GET_EMBED_KEYBOARD
|
||||
ES_SYSCALL_WINDOW_SET_BITS
|
||||
ES_SYSCALL_WINDOW_SET_CURSOR
|
||||
ES_SYSCALL_WINDOW_SET_PROPERTY
|
||||
|
@ -888,7 +889,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_SCROLL_WHEEL = 0x1011
|
||||
ES_MSG_WM_END = 0x13FF
|
||||
|
||||
// Internal GUI messages: // None of these should be sent directly.
|
||||
|
@ -1546,6 +1547,10 @@ struct EsMessageKeyboard {
|
|||
bool repeat, numpad, numlock, single;
|
||||
};
|
||||
|
||||
struct EsMessageScrollWheel {
|
||||
int32_t dx, dy;
|
||||
};
|
||||
|
||||
struct EsMessageAnimate {
|
||||
int64_t deltaMs, waitMs;
|
||||
bool complete;
|
||||
|
@ -1795,6 +1800,7 @@ struct EsMessage {
|
|||
EsMessageBeforeZOrder beforeZOrder;
|
||||
EsMessageItemToString itemToString;
|
||||
EsMessageFocus focus;
|
||||
EsMessageScrollWheel scrollWheel;
|
||||
const EsStyle *childStyleVariant;
|
||||
EsRectangle *accessKeyHintBounds;
|
||||
EsPainter *painter;
|
||||
|
|
|
@ -198,7 +198,7 @@ uint16_t scancodeConversionTable2[] = {
|
|||
|
||||
void PS2MouseUpdated(EsGeneric _update) {
|
||||
PS2Update *update = (PS2Update *) _update.p;
|
||||
KCursorUpdate(update->xMovement * K_CURSOR_MOVEMENT_SCALE, update->yMovement * K_CURSOR_MOVEMENT_SCALE, update->buttons);
|
||||
KMouseUpdate(update->xMovement * K_CURSOR_MOVEMENT_SCALE, update->yMovement * K_CURSOR_MOVEMENT_SCALE, update->buttons);
|
||||
}
|
||||
|
||||
void PS2KeyboardUpdated(EsGeneric _update) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include <module.h>
|
||||
|
||||
// #define TRACE_REPORTS
|
||||
|
||||
// TODO Key repeat not working on Qemu.
|
||||
|
||||
struct ReportItem {
|
||||
|
@ -101,6 +103,7 @@ struct UsageString {
|
|||
#define HID_USAGE_X_ROTATION (0x010033)
|
||||
#define HID_USAGE_Y_ROTATION (0x010034)
|
||||
#define HID_USAGE_Z_ROTATION (0x010035)
|
||||
#define HID_USAGE_WHEEL (0x010038)
|
||||
#define HID_USAGE_HAT_SWITCH (0x010039)
|
||||
#define HID_USAGE_KEYCODES (0x070000)
|
||||
#define HID_USAGE_BUTTON_1 (0x090001)
|
||||
|
@ -418,7 +421,8 @@ void HIDDevice::ReportReceived(BitBuffer *buffer) {
|
|||
#endif
|
||||
|
||||
bool mouseEvent = false;
|
||||
int mouseXMovement = 0, mouseYMovement = 0, mouseButtons = 0;
|
||||
int mouseXMovement = 0, mouseYMovement = 0;
|
||||
int mouseScrollWheel = 0, mouseButtons = 0;
|
||||
bool keyboardEvent = false;
|
||||
uint16_t keysDown[32];
|
||||
size_t keysDownCount = 0;
|
||||
|
@ -502,6 +506,8 @@ void HIDDevice::ReportReceived(BitBuffer *buffer) {
|
|||
if (buffer->ReadUnsigned(item->bits)) mouseButtons |= 1 << 2;
|
||||
} else if (item->usage == HID_USAGE_BUTTON_3) {
|
||||
if (buffer->ReadUnsigned(item->bits)) mouseButtons |= 1 << 1;
|
||||
} else if (item->usage == HID_USAGE_WHEEL) {
|
||||
mouseScrollWheel = buffer->ReadSigned(item->bits);
|
||||
} else {
|
||||
handled = false;
|
||||
}
|
||||
|
@ -559,9 +565,18 @@ void HIDDevice::ReportReceived(BitBuffer *buffer) {
|
|||
}
|
||||
}
|
||||
|
||||
if (mouseEvent) KCursorUpdate(mouseXMovement * K_CURSOR_MOVEMENT_SCALE, mouseYMovement * K_CURSOR_MOVEMENT_SCALE, mouseButtons);
|
||||
if (keyboardEvent) KKeyboardUpdate(keysDown, keysDownCount);
|
||||
if (gameControllerEvent) KGameControllerUpdateState(&controllerState);
|
||||
if (mouseEvent) {
|
||||
KMouseUpdate(mouseXMovement * K_CURSOR_MOVEMENT_SCALE, mouseYMovement * K_CURSOR_MOVEMENT_SCALE,
|
||||
mouseButtons, 0, mouseScrollWheel * ES_SCROLL_WHEEL_SCALE);
|
||||
}
|
||||
|
||||
if (keyboardEvent) {
|
||||
KKeyboardUpdate(keysDown, keysDownCount);
|
||||
}
|
||||
|
||||
if (gameControllerEvent) {
|
||||
KGameControllerUpdate(&controllerState);
|
||||
}
|
||||
|
||||
if (device->flags & K_DEVICE_REMOVED) {
|
||||
KDeviceCloseHandle(this);
|
||||
|
|
|
@ -364,14 +364,14 @@ void KTimerRemove(KTimer *timer); // Timers with callbacks cannot be removed (it
|
|||
// Window manager.
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define K_CURSOR_MOVEMENT_SCALE (0x100)
|
||||
void KCursorUpdate(int32_t xMovement, int32_t yMovement, uint32_t buttons);
|
||||
#define K_CURSOR_MOVEMENT_SCALE ES_SCROLL_WHEEL_SCALE
|
||||
void KMouseUpdate(int32_t xMovement, int32_t yMovement, uint32_t buttons, int32_t scrollX = 0, int32_t scrollY = 0);
|
||||
void KKeyboardUpdate(uint16_t *keysDown, size_t keysDownCount);
|
||||
void KKeyPress(uint32_t scancode);
|
||||
|
||||
uint64_t KGameControllerConnect();
|
||||
void KGameControllerDisconnect(uint64_t id);
|
||||
void KGameControllerUpdateState(EsGameControllerState *state);
|
||||
void KGameControllerUpdate(EsGameControllerState *state);
|
||||
|
||||
#define K_SCANCODE_KEY_RELEASED (1 << 15)
|
||||
#define K_SCANCODE_KEY_PRESSED (0 << 15)
|
||||
|
|
|
@ -1211,19 +1211,6 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WINDOW_GET_BOUNDS) {
|
|||
SYSCALL_RETURN(ES_SUCCESS, false);
|
||||
}
|
||||
|
||||
SYSCALL_IMPLEMENT(ES_SYSCALL_WINDOW_GET_EMBED_KEYBOARD) {
|
||||
SYSCALL_HANDLE(argument0, KERNEL_OBJECT_WINDOW, window, Window);
|
||||
_EsMessageWithObject m;
|
||||
EsMemoryZero(&m, sizeof(_EsMessageWithObject));
|
||||
KMutexAcquire(&windowManager.mutex);
|
||||
m.object = window->apiWindow;
|
||||
EsMemoryCopy(&m.message, &window->lastEmbedKeyboardMessage, sizeof(EsMessage));
|
||||
window->lastEmbedKeyboardMessage.type = ES_MSG_INVALID;
|
||||
KMutexRelease(&windowManager.mutex);
|
||||
SYSCALL_WRITE(argument1, &m, sizeof(_EsMessageWithObject));
|
||||
SYSCALL_RETURN(ES_SUCCESS, false);
|
||||
}
|
||||
|
||||
SYSCALL_IMPLEMENT(ES_SYSCALL_PROCESS_PAUSE) {
|
||||
SYSCALL_HANDLE(argument0, KERNEL_OBJECT_PROCESS, process, Process);
|
||||
scheduler.PauseProcess(process, (bool) argument1);
|
||||
|
|
|
@ -38,7 +38,6 @@ struct Window {
|
|||
EsRectangle solidInsets, embedInsets;
|
||||
bool solid, noClickActivate, hidden, isMaximised, alwaysOnTop, hoveringOverEmbed, queuedScrollUpdate, activationClick, noBringToFront;
|
||||
volatile bool closed;
|
||||
EsMessage lastEmbedKeyboardMessage; // The most recent keyboard message sent to the embedded window.
|
||||
|
||||
// Appearance:
|
||||
Surface surface;
|
||||
|
@ -66,8 +65,9 @@ struct WindowManager {
|
|||
void Initialise();
|
||||
|
||||
void MoveCursor(int64_t xMovement, int64_t yMovement);
|
||||
void ClickCursor(unsigned buttons);
|
||||
void PressKey(unsigned scancode);
|
||||
void ClickCursor(uint32_t buttons);
|
||||
void ScrollWheel(int32_t dx, int32_t dy);
|
||||
void PressKey(uint32_t scancode);
|
||||
|
||||
void Redraw(EsPoint position, int width, int height, Window *except = nullptr, int startingAt = 0, bool addToModifiedRegion = true);
|
||||
|
||||
|
@ -225,13 +225,16 @@ void SendMessageToWindow(Window *window, EsMessage *message) {
|
|||
} else {
|
||||
window->owner->messageQueue.SendMessage(window->apiWindow, message);
|
||||
}
|
||||
} else if (message->type == ES_MSG_SCROLL_WHEEL) {
|
||||
if (window->hoveringOverEmbed) {
|
||||
window->embed->owner->messageQueue.SendMessage(window->embed->apiWindow, message);
|
||||
} else {
|
||||
window->owner->messageQueue.SendMessage(window->apiWindow, message);
|
||||
}
|
||||
} else if (message->type == ES_MSG_KEY_DOWN || message->type == ES_MSG_KEY_UP) {
|
||||
// If the embedded window doesn't handle the key event,
|
||||
// then the container window can get it from here.
|
||||
// See DESKTOP_MSG_UNHANDLED_KEY_EVENT and ES_SYSCALL_WINDOW_GET_EMBED_KEYBOARD.
|
||||
EsMemoryCopy(&window->lastEmbedKeyboardMessage, message, sizeof(EsMessage));
|
||||
|
||||
// TODO Only send certain key messages to the container, like modifiers keys and global shortcuts.
|
||||
window->embed->owner->messageQueue.SendMessage(window->embed->apiWindow, message);
|
||||
window->owner->messageQueue.SendMessage(window->apiWindow, message);
|
||||
} else if (message->type == ES_MSG_MOUSE_EXIT) {
|
||||
window->embed->owner->messageQueue.SendMessage(window->embed->apiWindow, message);
|
||||
window->owner->messageQueue.SendMessage(window->apiWindow, message);
|
||||
|
@ -640,6 +643,18 @@ void WindowManager::MoveCursor(int64_t xMovement, int64_t yMovement) {
|
|||
GraphicsUpdateScreen();
|
||||
}
|
||||
|
||||
void WindowManager::ScrollWheel(int32_t dx, int32_t dy) {
|
||||
KMutexAssertLocked(&mutex);
|
||||
Window *window = pressedWindow ?: FindWindowAtPosition(cursorX, cursorY);
|
||||
if (!window) return;
|
||||
EsMessage message;
|
||||
EsMemoryZero(&message, sizeof(EsMessage));
|
||||
message.type = ES_MSG_SCROLL_WHEEL;
|
||||
message.scrollWheel.dx = dx;
|
||||
message.scrollWheel.dy = dy;
|
||||
SendMessageToWindow(window, &message);
|
||||
}
|
||||
|
||||
void _CloseWindows(uintptr_t) {
|
||||
while (true) {
|
||||
KEventWait(&windowManager.windowsToCloseEvent);
|
||||
|
@ -1208,7 +1223,7 @@ void WindowManager::StartEyedrop(uintptr_t object, Window *avoid, uint32_t cance
|
|||
KMutexRelease(&mutex);
|
||||
}
|
||||
|
||||
void KCursorUpdate(int xMovement, int yMovement, unsigned buttons) {
|
||||
void KMouseUpdate(int32_t xMovement, int32_t yMovement, uint32_t buttons, int32_t scrollX, int32_t scrollY) {
|
||||
if (!windowManager.initialised) {
|
||||
return;
|
||||
}
|
||||
|
@ -1223,6 +1238,12 @@ void KCursorUpdate(int xMovement, int yMovement, unsigned buttons) {
|
|||
}
|
||||
}
|
||||
|
||||
if (scrollX || scrollY) {
|
||||
KMutexAcquire(&windowManager.mutex);
|
||||
windowManager.ScrollWheel(scrollX, scrollY);
|
||||
KMutexRelease(&windowManager.mutex);
|
||||
}
|
||||
|
||||
windowManager.ClickCursor(buttons);
|
||||
}
|
||||
|
||||
|
@ -1314,7 +1335,7 @@ void KGameControllerDisconnect(uint64_t id) {
|
|||
KMutexRelease(&windowManager.gameControllersMutex);
|
||||
}
|
||||
|
||||
void KGameControllerUpdateState(EsGameControllerState *state) {
|
||||
void KGameControllerUpdate(EsGameControllerState *state) {
|
||||
KMutexAcquire(&windowManager.gameControllersMutex);
|
||||
|
||||
for (uintptr_t i = 0; i < windowManager.gameControllerCount; i++) {
|
||||
|
|
Loading…
Reference in New Issue