diff options
author | Andreas Kling <awesomekling@gmail.com> | 2018-10-14 01:23:01 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2018-10-14 01:23:01 +0200 |
commit | 959a1b0750328b59b25953bec7a9e8da95b3e058 (patch) | |
tree | b86c27ac2592d2083109493ac0cf056c526180a9 /Widgets | |
parent | 3ebea059961ec027ee0298e38201aa43f7e9451c (diff) | |
download | serenity-959a1b0750328b59b25953bec7a9e8da95b3e058.zip |
Close the MsgBox when clicking the OK button.
This feels vaguely crashy. I haven't tested window/widget destruction
before so there's sure to be bugs.
Diffstat (limited to 'Widgets')
-rw-r--r-- | Widgets/Event.h | 10 | ||||
-rw-r--r-- | Widgets/Object.cpp | 8 | ||||
-rw-r--r-- | Widgets/Object.h | 8 | ||||
-rw-r--r-- | Widgets/Widget.cpp | 2 | ||||
-rw-r--r-- | Widgets/Window.cpp | 11 | ||||
-rw-r--r-- | Widgets/Window.h | 4 | ||||
-rw-r--r-- | Widgets/WindowManager.cpp | 26 | ||||
-rw-r--r-- | Widgets/WindowManager.h | 4 | ||||
-rw-r--r-- | Widgets/test.cpp | 1 |
9 files changed, 65 insertions, 9 deletions
diff --git a/Widgets/Event.h b/Widgets/Event.h index ab63b0d0a9..07d675bab3 100644 --- a/Widgets/Event.h +++ b/Widgets/Event.h @@ -17,6 +17,7 @@ static const char* eventNames[] = { "KeyDown", "KeyUp", "Timer", + "DeferredDestroy", }; class Event { @@ -33,6 +34,7 @@ public: KeyDown, KeyUp, Timer, + DeferredDestroy, }; Event() { } @@ -53,6 +55,14 @@ private: Type m_type { Invalid }; }; +class DeferredDestroyEvent final : public Event { +public: + DeferredDestroyEvent() + : Event(Event::DeferredDestroy) + { + } +}; + class QuitEvent final : public Event { public: QuitEvent() diff --git a/Widgets/Object.cpp b/Widgets/Object.cpp index 0eaaed08f6..f5bb856be8 100644 --- a/Widgets/Object.cpp +++ b/Widgets/Object.cpp @@ -28,6 +28,9 @@ void Object::event(Event& event) switch (event.type()) { case Event::Timer: return timerEvent(static_cast<TimerEvent&>(event)); + case Event::DeferredDestroy: + delete this; + break; case Event::Invalid: ASSERT_NOT_REACHED(); break; @@ -82,3 +85,8 @@ void Object::stopTimer() m_timerID = 0; } +void Object::deleteLater() +{ + EventLoop::main().postEvent(this, make<DeferredDestroyEvent>()); +} + diff --git a/Widgets/Object.h b/Widgets/Object.h index 8bf27c8d19..f945350b88 100644 --- a/Widgets/Object.h +++ b/Widgets/Object.h @@ -24,12 +24,14 @@ public: void stopTimer(); bool hasTimer() const { return m_timerID; } -private: - virtual void timerEvent(TimerEvent&); - void addChild(Object&); void removeChild(Object&); + void deleteLater(); + +private: + virtual void timerEvent(TimerEvent&); + Object* m_parent { nullptr }; int m_timerID { 0 }; diff --git a/Widgets/Widget.cpp b/Widgets/Widget.cpp index 07b09b6583..e002834b3f 100644 --- a/Widgets/Widget.cpp +++ b/Widgets/Widget.cpp @@ -36,6 +36,8 @@ void Widget::event(Event& event) if (auto* win = window()) { if (win->isBeingDragged()) return; + if (!win->isVisible()) + return; } m_hasPendingPaintEvent = false; return paintEvent(static_cast<PaintEvent&>(event)); diff --git a/Widgets/Window.cpp b/Widgets/Window.cpp index c0ba0a2351..c281da1fd5 100644 --- a/Widgets/Window.cpp +++ b/Widgets/Window.cpp @@ -11,6 +11,10 @@ Window::Window(Object* parent) Window::~Window() { + delete m_mainWidget; + m_mainWidget = nullptr; + if (parent()) + parent()->removeChild(*this); WindowManager::the().removeWindow(*this); } @@ -96,6 +100,11 @@ bool Window::isActive() const return WindowManager::the().activeWindow() == this; } +bool Window::isVisible() const +{ + return WindowManager::the().isVisible(const_cast<Window&>(*this)); +} + void Window::setFocusedWidget(Widget* widget) { if (m_focusedWidget.ptr() == widget) @@ -113,5 +122,7 @@ void Window::setFocusedWidget(Widget* widget) void Window::close() { + WindowManager::the().removeWindow(*this); + deleteLater(); } diff --git a/Widgets/Window.h b/Widgets/Window.h index cf9d1006b8..2717e5a4e1 100644 --- a/Widgets/Window.h +++ b/Widgets/Window.h @@ -22,9 +22,11 @@ public: const Rect& rect() const { return m_rect; } void setRect(const Rect&); + void setRectWithoutRepaint(const Rect& rect) { m_rect = rect; } Point position() const { return m_rect.location(); } void setPosition(const Point& position) { setRect({ position.x(), position.y(), width(), height() }); } + void setPositionWithoutRepaint(const Point& position) { setRectWithoutRepaint({ position.x(), position.y(), width(), height() }); } Widget* mainWidget() { return m_mainWidget; } const Widget* mainWidget() const { return m_mainWidget; } @@ -44,6 +46,8 @@ public: const Widget* focusedWidget() const { return m_focusedWidget.ptr(); } void setFocusedWidget(Widget*); + bool isVisible() const; + void close(); private: diff --git a/Widgets/WindowManager.cpp b/Widgets/WindowManager.cpp index 6e21c5c646..c2d32ef7f0 100644 --- a/Widgets/WindowManager.cpp +++ b/Widgets/WindowManager.cpp @@ -126,22 +126,32 @@ void WindowManager::addWindow(Window& window) setActiveWindow(&window); } +void WindowManager::repaint() +{ + handlePaintEvent(*make<PaintEvent>()); +} + void WindowManager::removeWindow(Window& window) { - ASSERT(m_windows.contains(&window)); + if (!m_windows.contains(&window)) + return; + m_windows.remove(&window); if (!activeWindow() && !m_windows.isEmpty()) setActiveWindow(*m_windows.begin()); + + repaint(); } void WindowManager::notifyTitleChanged(Window& window) { - //printf("[WM] Window{%p} title set to '%s'\n", &window, window.title().characters()); + printf("[WM] Window{%p} title set to '%s'\n", &window, window.title().characters()); } void WindowManager::notifyRectChanged(Window& window, const Rect& oldRect, const Rect& newRect) { - //printf("[WM] Window %p rect changed (%d,%d %dx%d) -> (%d,%d %dx%d)\n", &window, oldRect.x(), oldRect.y(), oldRect.width(), oldRect.height(), newRect.x(), newRect.y(), newRect.width(), newRect.height()); + printf("[WM] Window %p rect changed (%d,%d %dx%d) -> (%d,%d %dx%d)\n", &window, oldRect.x(), oldRect.y(), oldRect.width(), oldRect.height(), newRect.x(), newRect.y(), newRect.width(), newRect.height()); + repaintAfterMove(oldRect, newRect); } void WindowManager::handleTitleBarMouseEvent(Window& window, MouseEvent& event) @@ -205,7 +215,7 @@ void WindowManager::processMouseEvent(MouseEvent& event) Point pos = m_dragWindowOrigin; printf("[WM] Dragging [origin: %d,%d] now: %d,%d\n", m_dragOrigin.x(), m_dragOrigin.y(), event.x(), event.y()); pos.moveBy(event.x() - m_dragOrigin.x(), event.y() - m_dragOrigin.y()); - m_dragWindow->setPosition(pos); + m_dragWindow->setPositionWithoutRepaint(pos); paintWindowFrame(*m_dragWindow); return; } @@ -243,9 +253,8 @@ void WindowManager::handlePaintEvent(PaintEvent& event) m_rootWidget->event(event); paintWindowFrames(); - for (auto* window : m_windows) { + for (auto* window : m_windows) window->event(event); - } } void WindowManager::event(Event& event) @@ -296,3 +305,8 @@ void WindowManager::setActiveWindow(Window* window) } } +bool WindowManager::isVisible(Window& window) const +{ + return m_windows.contains(&window); +} + diff --git a/Widgets/WindowManager.h b/Widgets/WindowManager.h index f53c29740e..02073ba3cb 100644 --- a/Widgets/WindowManager.h +++ b/Widgets/WindowManager.h @@ -27,6 +27,10 @@ public: Window* activeWindow() { return m_activeWindow.ptr(); } void setActiveWindow(Window*); + bool isVisible(Window&) const; + + void repaint(); + private: WindowManager(); ~WindowManager(); diff --git a/Widgets/test.cpp b/Widgets/test.cpp index 054c7e343b..ca72394d45 100644 --- a/Widgets/test.cpp +++ b/Widgets/test.cpp @@ -86,6 +86,7 @@ int main(int argc, char** argv) tb->onReturnPressed = [] (TextBox& textBox) { printf("TextBox %p return pressed: '%s'\n", &textBox, textBox.text().characters()); + MsgBox(nullptr, textBox.text()); }; WindowManager::the().setActiveWindow(widgetTestWindow); |