From f59d2329c904e8cb5f6509050444bf2aee4b8f65 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sun, 29 Nov 2015 09:32:52 +0100 Subject: Move event skip optimization fromNativeWindowXYZ to EventHandler --- plugingui/eventhandler.cc | 60 +++++++++++++++++++++++++++++++++++++++++ plugingui/eventhandler.h | 6 ++++- plugingui/nativewindow.h | 4 +++ plugingui/nativewindow_pugl.cc | 10 +++++++ plugingui/nativewindow_pugl.h | 1 + plugingui/nativewindow_win32.cc | 19 ++++++++++++- plugingui/nativewindow_win32.h | 1 + plugingui/nativewindow_x11.cc | 60 +++++++++++++---------------------------- plugingui/nativewindow_x11.h | 2 ++ 9 files changed, 120 insertions(+), 43 deletions(-) diff --git a/plugingui/eventhandler.cc b/plugingui/eventhandler.cc index 98e4cef..68f7f46 100644 --- a/plugingui/eventhandler.cc +++ b/plugingui/eventhandler.cc @@ -48,6 +48,11 @@ Event *EventHandler::getNextEvent() return nativeWindow.getNextEvent(); } +Event *EventHandler::peekNextEvent() +{ + return nativeWindow.peekNextEvent(); +} + void EventHandler::processEvents() { while(hasEvent()) @@ -68,6 +73,22 @@ void EventHandler::processEvents() case EventType::resize: { + while(true) + { + if(!hasEvent()) + { + break; + } + + auto peekEvent = peekNextEvent(); + if(!peekEvent || (peekEvent->type() != EventType::resize)) + { + break; + } + + event = getNextEvent(); + } + auto resizeEvent = static_cast(event); if((resizeEvent->width != window.width()) || (resizeEvent->height != window.height())) @@ -79,6 +100,22 @@ void EventHandler::processEvents() case EventType::mouseMove: { + while(true) + { + if(!hasEvent()) + { + break; + } + + auto peekEvent = peekNextEvent(); + if(!peekEvent || (peekEvent->type() != EventType::mouseMove)) + { + break; + } + + event = getNextEvent(); + } + auto moveEvent = static_cast(event); auto widget = window.find(moveEvent->x, moveEvent->y); @@ -173,7 +210,27 @@ void EventHandler::processEvents() case EventType::scroll: { + int delta = 0; + while(true) + { + if(!hasEvent()) + { + break; + } + + auto peekEvent = peekNextEvent(); + if(!peekEvent || (peekEvent->type() != EventType::scroll)) + { + break; + } + + auto scrollEvent = static_cast(event); + delta += scrollEvent->delta; + event = getNextEvent(); + } + auto scrollEvent = static_cast(event); + scrollEvent->delta += delta; auto widget = window.find(scrollEvent->x, scrollEvent->y); if(widget) @@ -188,6 +245,9 @@ void EventHandler::processEvents() case EventType::key: { + + // TODO: Filter out multiple arrow events. + auto keyEvent = static_cast(event); if(window.keyboardFocus()) { diff --git a/plugingui/eventhandler.h b/plugingui/eventhandler.h index 8fa42e4..b011f87 100644 --- a/plugingui/eventhandler.h +++ b/plugingui/eventhandler.h @@ -38,7 +38,7 @@ class EventHandler { public: EventHandler(NativeWindow& nativeWindow, Window& window); - //! \brief Process all evebts currently in the event queue. + //! \brief Process all events currently in the event queue. void processEvents(); //! \brief Query if any events are currently in the event queue. @@ -48,6 +48,10 @@ public: //! \return A pointer to the event or nullptr if there are none. Event *getNextEvent(); + //! \brief Get a single event from the event queue without popping it. + //! \return A pointer to the event or nullptr if there are none. + Event *peekNextEvent(); + Notifier<> closeNotifier; private: diff --git a/plugingui/nativewindow.h b/plugingui/nativewindow.h index 46891f2..a44693c 100644 --- a/plugingui/nativewindow.h +++ b/plugingui/nativewindow.h @@ -75,6 +75,10 @@ public: //! \brief Read a single event from the event queue. //! \return A pointer to the event or nullptr is none exists. virtual Event *getNextEvent() = 0; + + //! \brief Read next event without popping it from the event queue. + //! \return A pointer to the event or nullptr is none exists. + virtual Event* peekNextEvent() = 0; }; } // GUI:: diff --git a/plugingui/nativewindow_pugl.cc b/plugingui/nativewindow_pugl.cc index 0864c2b..b9dcd54 100644 --- a/plugingui/nativewindow_pugl.cc +++ b/plugingui/nativewindow_pugl.cc @@ -243,4 +243,14 @@ Event *NativeWindowPugl::getNextEvent() return event; } +Event *NativeWindowPugl::peekNextEvent() +{ + Event *event = nullptr; + + if(!eventq.empty()) { + event = eventq.front(); + } + return event; +} + } // GUI:: diff --git a/plugingui/nativewindow_pugl.h b/plugingui/nativewindow_pugl.h index f5d89ab..335e7e4 100644 --- a/plugingui/nativewindow_pugl.h +++ b/plugingui/nativewindow_pugl.h @@ -54,6 +54,7 @@ public: bool hasEvent(); Event *getNextEvent(); + Event *peekNextEvent(); private: Window* window{nullptr}; diff --git a/plugingui/nativewindow_win32.cc b/plugingui/nativewindow_win32.cc index 9f8936f..72e0598 100644 --- a/plugingui/nativewindow_win32.cc +++ b/plugingui/nativewindow_win32.cc @@ -411,7 +411,7 @@ void NativeWindowWin32::grabMouse(bool grab) bool NativeWindowWin32::hasEvent() { MSG msg; - return PeekMessage(&msg, nullptr, 0, 0, 0) != 0; + return PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE) != 0; } Event* NativeWindowWin32::getNextEvent() @@ -431,4 +431,21 @@ Event* NativeWindowWin32::getNextEvent() return event; } +Event* NativeWindowWin32::peekNextEvent() +{ + Event* event = nullptr; + + MSG msg; + if(PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + event = this->event; + this->event = nullptr; + + return event; +} + } // GUI:: diff --git a/plugingui/nativewindow_win32.h b/plugingui/nativewindow_win32.h index 57172f4..fa4b6bc 100644 --- a/plugingui/nativewindow_win32.h +++ b/plugingui/nativewindow_win32.h @@ -54,6 +54,7 @@ public: bool hasEvent() override; Event* getNextEvent() override; + Event* peekNextEvent() override; private: static LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); diff --git a/plugingui/nativewindow_x11.cc b/plugingui/nativewindow_x11.cc index d47c67f..02ee653 100644 --- a/plugingui/nativewindow_x11.cc +++ b/plugingui/nativewindow_x11.cc @@ -353,30 +353,29 @@ Event* NativeWindowX11::getNextEvent() return nullptr; } - Event* event = nullptr; - - XEvent xevent; - XNextEvent(display, &xevent); + XEvent xEvent; + XNextEvent(display, &xEvent); + return translateXMessage(xEvent); +} - if(xevent.type == MotionNotify) +Event* NativeWindowX11::peekNextEvent() +{ + if(display == nullptr) { - while(true) // Hack to make sure only the last event is played. - { - if(!hasEvent()) - { - break; - } + return nullptr; + } - XEvent peekXEvent; - XPeekEvent(display, &peekXEvent); - if(peekXEvent.type != MotionNotify) - { - break; - } + XEvent peekXEvent; + XPeekEvent(display, &peekXEvent); + return translateXMessage(peekXEvent); +} - XNextEvent(display, &xevent); - } +Event* NativeWindowX11::translateXMessage(XEvent& xevent) +{ + Event* event = nullptr; + if(xevent.type == MotionNotify) + { auto mouseMoveEvent = new MouseMoveEvent(); mouseMoveEvent->window_id = xevent.xmotion.window; mouseMoveEvent->x = xevent.xmotion.x; @@ -411,26 +410,6 @@ Event* NativeWindowX11::getNextEvent() if((xevent.xbutton.button == 4) || (xevent.xbutton.button == 5)) { int scroll = 1; - while(true) // Hack to make sure only the last event is played. - { - if(!hasEvent()) - { - break; - } - - XEvent peekXEvent; - XPeekEvent(display, &peekXEvent); - - if((peekXEvent.type != ButtonPress) && - (peekXEvent.type != ButtonRelease)) - { - break; - } - - scroll += 1; - XNextEvent(display, &xevent); - } - auto scrollEvent = new ScrollEvent(); scrollEvent->window_id = xevent.xbutton.window; scrollEvent->x = xevent.xbutton.x; @@ -455,7 +434,7 @@ Event* NativeWindowX11::getNextEvent() buttonEvent->button = MouseButton::right; break; default: - WARN(X11, "Unknown button %d, setting to Left\n", + WARN(X11, "Unknown button %d, setting to MouseButton::left\n", xevent.xbutton.button); buttonEvent->button = MouseButton::left; break; @@ -479,7 +458,6 @@ Event* NativeWindowX11::getNextEvent() if(xevent.type == KeyPress || xevent.type == KeyRelease) { - //printf("key: %d\n", xevent.xkey.keycode); auto keyEvent = new KeyEvent(); keyEvent->window_id = xevent.xkey.window; diff --git a/plugingui/nativewindow_x11.h b/plugingui/nativewindow_x11.h index fb43457..2529631 100644 --- a/plugingui/nativewindow_x11.h +++ b/plugingui/nativewindow_x11.h @@ -50,8 +50,10 @@ public: void grabMouse(bool grab) override; bool hasEvent() override; Event* getNextEvent() override; + Event* peekNextEvent() override; private: + Event* translateXMessage(XEvent& xevent); XImage* createImageFromBuffer(unsigned char* buf, int width, int height); ::Window xwindow; -- cgit v1.2.3