mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 08:32:43 +00:00 
			
		
		
		
	Start bringing up LibGUI properly (formerly Widgets.)
This commit is contained in:
		
							parent
							
								
									b91479d9b9
								
							
						
					
					
						commit
						8eae89a405
					
				
					 17 changed files with 258 additions and 33 deletions
				
			
		|  | @ -104,6 +104,7 @@ static void init_stage2() | |||
|     Process::create_user_process("/bin/Terminal", (uid_t)100, (gid_t)100, (pid_t)0, error, { }, move(environment), tty0); | ||||
| #ifdef SPAWN_GUI_TEST_APP | ||||
|     Process::create_user_process("/bin/guitest", (uid_t)100, (gid_t)100, (pid_t)0, error, { }, move(environment), tty0); | ||||
|     Process::create_user_process("/bin/guitest2", (uid_t)100, (gid_t)100, (pid_t)0, error, { }, move(environment), tty0); | ||||
| #endif | ||||
| #ifdef SPAWN_MULTIPLE_SHELLS | ||||
|     Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, { }, { }, tty1); | ||||
|  |  | |||
|  | @ -4,6 +4,10 @@ sudo id | |||
| 
 | ||||
| make -C ../LibC clean && \ | ||||
| make -C ../LibC && \ | ||||
| make -C ../LibGUI clean && \ | ||||
| make -C ../LibGUI && \ | ||||
| make -C ../Terminal clean && \ | ||||
| make -C ../Terminal && \ | ||||
| make -C ../Userland clean && \ | ||||
| make -C ../Userland && \ | ||||
| sudo ./sync.sh | ||||
|  |  | |||
|  | @ -43,6 +43,7 @@ cp -v ../Userland/touch mnt/bin/touch | |||
| cp -v ../Userland/sync mnt/bin/sync | ||||
| cp -v ../Userland/more mnt/bin/more | ||||
| cp -v ../Userland/guitest mnt/bin/guitest | ||||
| cp -v ../Userland/guitest2 mnt/bin/guitest2 | ||||
| cp -v ../Userland/sysctl mnt/bin/sysctl | ||||
| cp -v ../Terminal/Terminal mnt/bin/Terminal | ||||
| sh sync-local.sh | ||||
|  |  | |||
|  | @ -134,9 +134,9 @@ private: | |||
| 
 | ||||
| class GMouseEvent final : public GEvent { | ||||
| public: | ||||
|     GMouseEvent(Type type, int x, int y, GMouseButton button = GMouseButton::None) | ||||
|     GMouseEvent(Type type, const Point& position, GMouseButton button = GMouseButton::None) | ||||
|         : GEvent(type) | ||||
|         , m_position(x, y) | ||||
|         , m_position(position) | ||||
|         , m_button(button) | ||||
|     { | ||||
|     } | ||||
|  |  | |||
|  | @ -1,6 +1,13 @@ | |||
| #include "GEventLoop.h" | ||||
| #include "GEvent.h" | ||||
| #include "GObject.h" | ||||
| #include "GWindow.h" | ||||
| #include <LibC/unistd.h> | ||||
| #include <LibC/stdio.h> | ||||
| #include <LibC/fcntl.h> | ||||
| #include <LibC/string.h> | ||||
| #include <LibC/sys/select.h> | ||||
| #include <LibC/gui.h> | ||||
| 
 | ||||
| static GEventLoop* s_mainGEventLoop; | ||||
| 
 | ||||
|  | @ -27,13 +34,19 @@ GEventLoop& GEventLoop::main() | |||
| 
 | ||||
| int GEventLoop::exec() | ||||
| { | ||||
|     m_event_fd = open("/dev/gui_events", O_RDONLY); | ||||
|     if (m_event_fd < 0) { | ||||
|         perror("GEventLoop::exec(): open"); | ||||
|         exit(1); | ||||
|     } | ||||
| 
 | ||||
|     m_running = true; | ||||
|     for (;;) { | ||||
|         if (m_queuedEvents.is_empty()) | ||||
|             waitForEvent(); | ||||
|         if (m_queued_events.is_empty()) | ||||
|             wait_for_event(); | ||||
|         Vector<QueuedEvent> events; | ||||
|         { | ||||
|             events = move(m_queuedEvents); | ||||
|             events = move(m_queued_events); | ||||
|         } | ||||
|         for (auto& queuedEvent : events) { | ||||
|             auto* receiver = queuedEvent.receiver; | ||||
|  | @ -56,12 +69,81 @@ int GEventLoop::exec() | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void GEventLoop::postEvent(GObject* receiver, OwnPtr<GEvent>&& event) | ||||
| void GEventLoop::post_event(GObject* receiver, OwnPtr<GEvent>&& event) | ||||
| { | ||||
|     //printf("GEventLoop::postGEvent: {%u} << receiver=%p, event=%p\n", m_queuedEvents.size(), receiver, event.ptr());
 | ||||
|     m_queuedEvents.append({ receiver, move(event) }); | ||||
|     m_queued_events.append({ receiver, move(event) }); | ||||
| } | ||||
| 
 | ||||
| void GEventLoop::waitForEvent() | ||||
| void GEventLoop::handle_paint_event(const GUI_Event& event, GWindow& window) | ||||
| { | ||||
|     post_event(&window, make<GPaintEvent>(event.paint.rect)); | ||||
| } | ||||
| 
 | ||||
| void GEventLoop::handle_mouse_event(const GUI_Event& event, GWindow& window) | ||||
| { | ||||
|     GMouseEvent::Type type; | ||||
|     switch (event.type) { | ||||
|     case GUI_Event::Type::MouseMove: type = GEvent::MouseMove; break; | ||||
|     case GUI_Event::Type::MouseUp: type = GEvent::MouseUp; break; | ||||
|     case GUI_Event::Type::MouseDown: type = GEvent::MouseDown; break; | ||||
|     default: ASSERT_NOT_REACHED(); break; | ||||
|     } | ||||
|     GMouseButton button { GMouseButton::None }; | ||||
|     switch (event.mouse.button) { | ||||
|     case GUI_MouseButton::NoButton: button = GMouseButton::None; break; | ||||
|     case GUI_MouseButton::Left: button = GMouseButton::Left; break; | ||||
|     case GUI_MouseButton::Right: button = GMouseButton::Right; break; | ||||
|     case GUI_MouseButton::Middle: button = GMouseButton::Middle; break; | ||||
|     default: ASSERT_NOT_REACHED(); break; | ||||
|     } | ||||
|     auto mouse_event = make<GMouseEvent>(type, event.mouse.position, button); | ||||
| } | ||||
| 
 | ||||
| void GEventLoop::wait_for_event() | ||||
| { | ||||
|     fd_set rfds; | ||||
|     FD_ZERO(&rfds); | ||||
|     FD_SET(m_event_fd, &rfds); | ||||
|     int rc = select(m_event_fd + 1, &rfds, nullptr, nullptr, nullptr); | ||||
|     if (rc < 0) { | ||||
|         ASSERT_NOT_REACHED(); | ||||
|     } | ||||
| 
 | ||||
|     if (!FD_ISSET(m_event_fd, &rfds)) | ||||
|         return; | ||||
| 
 | ||||
|     for (;;) { | ||||
|         GUI_Event event; | ||||
|         ssize_t nread = read(m_event_fd, &event, sizeof(GUI_Event)); | ||||
|         if (nread < 0) { | ||||
|             perror("read"); | ||||
|             exit(1); // FIXME: This should cause EventLoop::exec() to return 1.
 | ||||
|         } | ||||
|         if (nread == 0) | ||||
|             break; | ||||
|         assert(nread == sizeof(event)); | ||||
|         auto* window = GWindow::from_window_id(event.window_id); | ||||
|         if (!window) { | ||||
|             dbgprintf("GEventLoop received event for invalid window ID %d\n", event.window_id); | ||||
|         } | ||||
|         switch (event.type) { | ||||
|         case GUI_Event::Type::Paint: | ||||
|             dbgprintf("WID=%x Paint [%d,%d %dx%d]\n", event.window_id, event.paint.rect.location.x, event.paint.rect.location.y, event.paint.rect.size.width, event.paint.rect.size.height); break; | ||||
|             handle_paint_event(event, *window); | ||||
|             break; | ||||
|         case GUI_Event::Type::MouseDown: | ||||
|         case GUI_Event::Type::MouseUp: | ||||
|         case GUI_Event::Type::MouseMove: | ||||
|             dbgprintf("WID=%x MouseEvent %d,%d\n", event.window_id, event.mouse.position.x, event.mouse.position.y); | ||||
|             handle_mouse_event(event, *window); | ||||
|             break; | ||||
|         case GUI_Event::Type::WindowActivated: | ||||
|             dbgprintf("WID=%x WindowActivated\n", event.window_id); | ||||
|             break; | ||||
|         case GUI_Event::Type::WindowDeactivated: | ||||
|             dbgprintf("WID=%x WindowDeactivated\n", event.window_id); | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -5,6 +5,8 @@ | |||
| #include <AK/Vector.h> | ||||
| 
 | ||||
| class GObject; | ||||
| class GWindow; | ||||
| struct GUI_Event; | ||||
| 
 | ||||
| class GEventLoop { | ||||
| public: | ||||
|  | @ -13,7 +15,7 @@ public: | |||
| 
 | ||||
|     int exec(); | ||||
| 
 | ||||
|     void postEvent(GObject* receiver, OwnPtr<GEvent>&&); | ||||
|     void post_event(GObject* receiver, OwnPtr<GEvent>&&); | ||||
| 
 | ||||
|     static GEventLoop& main(); | ||||
| 
 | ||||
|  | @ -22,13 +24,16 @@ public: | |||
|     bool running() const { return m_running; } | ||||
| 
 | ||||
| private: | ||||
|     void waitForEvent(); | ||||
|     void wait_for_event(); | ||||
|     void handle_paint_event(const GUI_Event&, GWindow&); | ||||
|     void handle_mouse_event(const GUI_Event&, GWindow&); | ||||
| 
 | ||||
|     struct QueuedEvent { | ||||
|         GObject* receiver { nullptr }; | ||||
|         OwnPtr<GEvent> event; | ||||
|     }; | ||||
|     Vector<QueuedEvent> m_queuedEvents; | ||||
|     Vector<QueuedEvent> m_queued_events; | ||||
| 
 | ||||
|     int m_event_fd { -1 }; | ||||
|     bool m_running { false }; | ||||
| }; | ||||
|  |  | |||
|  | @ -71,6 +71,6 @@ void GObject::stopTimer() | |||
| 
 | ||||
| void GObject::deleteLater() | ||||
| { | ||||
|     GEventLoop::main().postEvent(this, make<GEvent>(GEvent::DeferredDestroy)); | ||||
|     GEventLoop::main().post_event(this, make<GEvent>(GEvent::DeferredDestroy)); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -37,8 +37,6 @@ void GWidget::event(GEvent& event) | |||
|     case GEvent::Paint: | ||||
|         m_hasPendingPaintEvent = false; | ||||
|         if (auto* win = window()) { | ||||
|             if (win->is_being_dragged()) | ||||
|                 return; | ||||
|             if (!win->is_visible()) | ||||
|                 return; | ||||
|         } | ||||
|  | @ -112,7 +110,7 @@ void GWidget::update() | |||
|     if (m_hasPendingPaintEvent) | ||||
|         return; | ||||
|     m_hasPendingPaintEvent = true; | ||||
|     GEventLoop::main().postEvent(w, make<GPaintEvent>(relativeRect())); | ||||
|     GEventLoop::main().post_event(w, make<GPaintEvent>(relativeRect())); | ||||
| } | ||||
| 
 | ||||
| GWidget::HitTestResult GWidget::hitTest(int x, int y) | ||||
|  |  | |||
|  | @ -2,10 +2,51 @@ | |||
| #include "GEvent.h" | ||||
| #include "GEventLoop.h" | ||||
| #include <SharedGraphics/GraphicsBitmap.h> | ||||
| #include <LibC/gui.h> | ||||
| #include <LibC/stdio.h> | ||||
| #include <LibC/stdlib.h> | ||||
| #include <AK/HashMap.h> | ||||
| 
 | ||||
| GWindow::GWindow(int window_id) | ||||
|     : m_window_id(window_id) | ||||
| static HashMap<int, GWindow*>* s_windows; | ||||
| 
 | ||||
| static HashMap<int, GWindow*>& windows() | ||||
| { | ||||
|     if (!s_windows) | ||||
|         s_windows = new HashMap<int, GWindow*>; | ||||
|     return *s_windows; | ||||
| } | ||||
| 
 | ||||
| GWindow* GWindow::from_window_id(int window_id) | ||||
| { | ||||
|     auto it = windows().find(window_id); | ||||
|     if (it != windows().end()) | ||||
|         return (*it).value; | ||||
|     return nullptr; | ||||
| } | ||||
| 
 | ||||
| GWindow::GWindow(GObject* parent) | ||||
|     : GObject(parent) | ||||
| { | ||||
|     GUI_CreateWindowParameters wparams; | ||||
|     wparams.rect = { { 100, 400 }, { 140, 140 } }; | ||||
|     wparams.background_color = 0xffc0c0; | ||||
|     strcpy(wparams.title, "GWindow"); | ||||
|     m_window_id = gui_create_window(&wparams); | ||||
|     if (m_window_id < 0) { | ||||
|         perror("gui_create_window"); | ||||
|         exit(1); | ||||
|     } | ||||
| 
 | ||||
|     GUI_WindowBackingStoreInfo backing; | ||||
|     int rc = gui_get_window_backing_store(m_window_id, &backing); | ||||
|     if (rc < 0) { | ||||
|         perror("gui_get_window_backing_store"); | ||||
|         exit(1); | ||||
|     } | ||||
| 
 | ||||
|     m_backing = GraphicsBitmap::create_wrapper(backing.size, backing.pixels); | ||||
| 
 | ||||
|     windows().set(m_window_id, this); | ||||
| } | ||||
| 
 | ||||
| GWindow::~GWindow() | ||||
|  | @ -40,3 +81,19 @@ void GWindow::close() | |||
| { | ||||
| } | ||||
| 
 | ||||
| void GWindow::show() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void GWindow::update() | ||||
| { | ||||
|     gui_invalidate_window(m_window_id, nullptr); | ||||
| } | ||||
| 
 | ||||
| void GWindow::set_main_widget(GWidget* widget) | ||||
| { | ||||
|     if (m_main_widget == widget) | ||||
|         return; | ||||
|     m_main_widget = widget; | ||||
|     update(); | ||||
| } | ||||
|  |  | |||
|  | @ -5,11 +5,15 @@ | |||
| #include <SharedGraphics/GraphicsBitmap.h> | ||||
| #include <AK/AKString.h> | ||||
| 
 | ||||
| class GWidget; | ||||
| 
 | ||||
| class GWindow final : public GObject { | ||||
| public: | ||||
|     explicit GWindow(int window_id); | ||||
|     GWindow(GObject* parent = nullptr); | ||||
|     virtual ~GWindow() override; | ||||
| 
 | ||||
|     static GWindow* from_window_id(int); | ||||
| 
 | ||||
|     int window_id() const { return m_window_id; } | ||||
| 
 | ||||
|     String title() const { return m_title; } | ||||
|  | @ -29,21 +33,24 @@ public: | |||
| 
 | ||||
|     virtual void event(GEvent&) override; | ||||
| 
 | ||||
|     bool is_being_dragged() const { return m_is_being_dragged; } | ||||
|     void set_is_being_dragged(bool b) { m_is_being_dragged = b; } | ||||
| 
 | ||||
|     bool is_visible() const; | ||||
| 
 | ||||
|     void close(); | ||||
| 
 | ||||
|     void set_main_widget(GWidget*); | ||||
| 
 | ||||
|     GraphicsBitmap* backing() { return m_backing.ptr(); } | ||||
| 
 | ||||
|     void show(); | ||||
| 
 | ||||
|     void update(); | ||||
| 
 | ||||
| private: | ||||
|     String m_title; | ||||
|     Rect m_rect; | ||||
|     bool m_is_being_dragged { false }; | ||||
| 
 | ||||
|     RetainPtr<GraphicsBitmap> m_backing; | ||||
|     int m_window_id { -1 }; | ||||
|     GWidget* m_main_widget { nullptr }; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										1
									
								
								Userland/.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								Userland/.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -22,4 +22,5 @@ touch | |||
| sync | ||||
| more | ||||
| guitest | ||||
| guitest2 | ||||
| sysctl | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ OBJS = \ | |||
|        touch.o \
 | ||||
|        more.o \
 | ||||
|        guitest.o \
 | ||||
|        guitest2.o \
 | ||||
|        sysctl.o | ||||
| 
 | ||||
| APPS = \
 | ||||
|  | @ -45,6 +46,7 @@ APPS = \ | |||
|        sync \
 | ||||
|        more \
 | ||||
|        guitest \
 | ||||
|        guitest2 \
 | ||||
|        sysctl | ||||
| 
 | ||||
| ARCH_FLAGS = | ||||
|  | @ -131,6 +133,9 @@ more: more.o | |||
| guitest: guitest.o | ||||
| 	$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a | ||||
| 
 | ||||
| guitest2: guitest2.o | ||||
| 	$(LD) -o $@ $(LDFLAGS) $< ../LibGUI/LibGUI.a ../LibC/LibC.a | ||||
| 
 | ||||
| sysctl: sysctl.o | ||||
| 	$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										54
									
								
								Userland/guitest2.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								Userland/guitest2.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | |||
| #include <stdio.h> | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <fcntl.h> | ||||
| #include <assert.h> | ||||
| #include <Kernel/Syscall.h> | ||||
| #include <SharedGraphics/GraphicsBitmap.h> | ||||
| #include <SharedGraphics/Painter.h> | ||||
| #include <LibGUI/GWindow.h> | ||||
| #include <LibGUI/GWidget.h> | ||||
| #include <LibGUI/GLabel.h> | ||||
| #include <LibGUI/GEventLoop.h> | ||||
| 
 | ||||
| static GWindow* make_font_test_window(); | ||||
| 
 | ||||
| int main(int argc, char** argv) | ||||
| { | ||||
|     auto* window = make_font_test_window(); | ||||
|     window->show(); | ||||
| 
 | ||||
|     GEventLoop loop; | ||||
|     return loop.exec(); | ||||
| } | ||||
| 
 | ||||
| GWindow* make_font_test_window() | ||||
| { | ||||
|     auto* window = new GWindow; | ||||
|     window->set_title("Font test"); | ||||
|     window->set_rect({ 140, 100, 300, 80 }); | ||||
| 
 | ||||
|     auto* widget = new GWidget; | ||||
|     window->set_main_widget(widget); | ||||
|     widget->setWindowRelativeRect({ 0, 0, 300, 80 }); | ||||
| 
 | ||||
|     auto* l1 = new GLabel(widget); | ||||
|     l1->setWindowRelativeRect({ 0, 0, 300, 20 }); | ||||
|     l1->setText("0123456789"); | ||||
| 
 | ||||
|     auto* l2 = new GLabel(widget); | ||||
|     l2->setWindowRelativeRect({ 0, 20, 300, 20 }); | ||||
|     l2->setText("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); | ||||
| 
 | ||||
|     auto* l3 = new GLabel(widget); | ||||
|     l3->setWindowRelativeRect({ 0, 40, 300, 20 }); | ||||
|     l3->setText("abcdefghijklmnopqrstuvwxyz"); | ||||
| 
 | ||||
|     auto* l4 = new GLabel(widget); | ||||
|     l4->setWindowRelativeRect({ 0, 60, 300, 20 }); | ||||
|     l4->setText("!\"#$%&'()*+,-./:;<=>?@[\\]^_{|}~"); | ||||
| 
 | ||||
|     return window; | ||||
| } | ||||
|  | @ -80,9 +80,9 @@ private: | |||
| 
 | ||||
| enum class MouseButton : byte { | ||||
|     None = 0, | ||||
|     Left, | ||||
|     Middle, | ||||
|     Right, | ||||
|     Left = 1, | ||||
|     Right = 2, | ||||
|     Middle = 4, | ||||
| }; | ||||
| 
 | ||||
| enum KeyboardKey { | ||||
|  | @ -121,9 +121,10 @@ private: | |||
| 
 | ||||
| class MouseEvent final : public WSEvent { | ||||
| public: | ||||
|     MouseEvent(Type type, int x, int y, MouseButton button = MouseButton::None) | ||||
|     MouseEvent(Type type, const Point& position, unsigned buttons, MouseButton button = MouseButton::None) | ||||
|         : WSEvent(type) | ||||
|         , m_position(x, y) | ||||
|         , m_position(position) | ||||
|         , m_buttons(buttons) | ||||
|         , m_button(button) | ||||
|     { | ||||
|     } | ||||
|  | @ -132,8 +133,10 @@ public: | |||
|     int x() const { return m_position.x(); } | ||||
|     int y() const { return m_position.y(); } | ||||
|     MouseButton button() const { return m_button; } | ||||
|     unsigned buttons() const { return m_buttons; } | ||||
| 
 | ||||
| private: | ||||
|     Point m_position; | ||||
|     unsigned m_buttons { 0 }; | ||||
|     MouseButton m_button { MouseButton::None }; | ||||
| }; | ||||
|  |  | |||
|  | @ -41,8 +41,13 @@ void WSScreen::on_receive_mouse_data(int dx, int dy, bool left_button, bool righ | |||
|         m_cursor_location.set_x(width() - 1); | ||||
|     if (m_cursor_location.y() >= height()) | ||||
|         m_cursor_location.set_y(height() - 1); | ||||
|     unsigned buttons = 0; | ||||
|     if (left_button) | ||||
|         buttons |= (unsigned)MouseButton::Left; | ||||
|     if (right_button) | ||||
|         buttons |= (unsigned)MouseButton::Right; | ||||
|     if (m_cursor_location != prev_location) { | ||||
|         auto event = make<MouseEvent>(WSEvent::MouseMove, m_cursor_location.x(), m_cursor_location.y()); | ||||
|         auto event = make<MouseEvent>(WSEvent::MouseMove, m_cursor_location, buttons); | ||||
|         WSEventLoop::the().post_event(&WSWindowManager::the(), move(event)); | ||||
|     } | ||||
|     bool prev_left_button = m_left_mouse_button_pressed; | ||||
|  | @ -50,11 +55,11 @@ void WSScreen::on_receive_mouse_data(int dx, int dy, bool left_button, bool righ | |||
|     m_left_mouse_button_pressed = left_button; | ||||
|     m_right_mouse_button_pressed = right_button; | ||||
|     if (prev_left_button != left_button) { | ||||
|         auto event = make<MouseEvent>(left_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location.x(), m_cursor_location.y(), MouseButton::Left); | ||||
|         auto event = make<MouseEvent>(left_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location, buttons, MouseButton::Left); | ||||
|         WSEventLoop::the().post_event(&WSWindowManager::the(), move(event)); | ||||
|     } | ||||
|     if (prev_right_button != right_button) { | ||||
|         auto event = make<MouseEvent>(right_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location.x(), m_cursor_location.y(), MouseButton::Right); | ||||
|         auto event = make<MouseEvent>(right_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location, buttons, MouseButton::Right); | ||||
|         WSEventLoop::the().post_event(&WSWindowManager::the(), move(event)); | ||||
|     } | ||||
|     if (m_cursor_location != prev_location || prev_left_button != left_button) | ||||
|  |  | |||
|  | @ -59,6 +59,7 @@ void WSWindow::event(WSEvent& event) | |||
|     case WSEvent::MouseMove: | ||||
|         gui_event.type = GUI_Event::Type::MouseMove; | ||||
|         gui_event.mouse.position = static_cast<MouseEvent&>(event).position(); | ||||
|         gui_event.mouse.button = GUI_MouseButton::NoButton; | ||||
|         break; | ||||
|     case WSEvent::MouseDown: | ||||
|         gui_event.type = GUI_Event::Type::MouseDown; | ||||
|  |  | |||
|  | @ -285,9 +285,10 @@ void WSWindowManager::process_mouse_event(MouseEvent& event) | |||
|                 move_to_front(*window); | ||||
|                 set_active_window(window); | ||||
|             } | ||||
|             // FIXME: Re-use the existing event instead of crafting a new one?
 | ||||
|             auto localEvent = make<MouseEvent>(event.type(), event.x() - window->rect().x(), event.y() - window->rect().y(), event.button()); | ||||
|             window->event(*localEvent); | ||||
|             // FIXME: Should we just alter the coordinates of the existing MouseEvent and pass it through?
 | ||||
|             Point position { event.x() - window->rect().x(), event.y() - window->rect().y() }; | ||||
|             auto local_event = make<MouseEvent>(event.type(), position, event.buttons(), event.button()); | ||||
|             window->event(*local_event); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling