1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 06:47:35 +00:00

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.
This commit is contained in:
Andreas Kling 2018-10-14 01:23:01 +02:00
parent 3ebea05996
commit 959a1b0750
9 changed files with 65 additions and 9 deletions

View file

@ -17,6 +17,7 @@ static const char* eventNames[] = {
"KeyDown", "KeyDown",
"KeyUp", "KeyUp",
"Timer", "Timer",
"DeferredDestroy",
}; };
class Event { class Event {
@ -33,6 +34,7 @@ public:
KeyDown, KeyDown,
KeyUp, KeyUp,
Timer, Timer,
DeferredDestroy,
}; };
Event() { } Event() { }
@ -53,6 +55,14 @@ private:
Type m_type { Invalid }; Type m_type { Invalid };
}; };
class DeferredDestroyEvent final : public Event {
public:
DeferredDestroyEvent()
: Event(Event::DeferredDestroy)
{
}
};
class QuitEvent final : public Event { class QuitEvent final : public Event {
public: public:
QuitEvent() QuitEvent()

View file

@ -28,6 +28,9 @@ void Object::event(Event& event)
switch (event.type()) { switch (event.type()) {
case Event::Timer: case Event::Timer:
return timerEvent(static_cast<TimerEvent&>(event)); return timerEvent(static_cast<TimerEvent&>(event));
case Event::DeferredDestroy:
delete this;
break;
case Event::Invalid: case Event::Invalid:
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
break; break;
@ -82,3 +85,8 @@ void Object::stopTimer()
m_timerID = 0; m_timerID = 0;
} }
void Object::deleteLater()
{
EventLoop::main().postEvent(this, make<DeferredDestroyEvent>());
}

View file

@ -24,12 +24,14 @@ public:
void stopTimer(); void stopTimer();
bool hasTimer() const { return m_timerID; } bool hasTimer() const { return m_timerID; }
private:
virtual void timerEvent(TimerEvent&);
void addChild(Object&); void addChild(Object&);
void removeChild(Object&); void removeChild(Object&);
void deleteLater();
private:
virtual void timerEvent(TimerEvent&);
Object* m_parent { nullptr }; Object* m_parent { nullptr };
int m_timerID { 0 }; int m_timerID { 0 };

View file

@ -36,6 +36,8 @@ void Widget::event(Event& event)
if (auto* win = window()) { if (auto* win = window()) {
if (win->isBeingDragged()) if (win->isBeingDragged())
return; return;
if (!win->isVisible())
return;
} }
m_hasPendingPaintEvent = false; m_hasPendingPaintEvent = false;
return paintEvent(static_cast<PaintEvent&>(event)); return paintEvent(static_cast<PaintEvent&>(event));

View file

@ -11,6 +11,10 @@ Window::Window(Object* parent)
Window::~Window() Window::~Window()
{ {
delete m_mainWidget;
m_mainWidget = nullptr;
if (parent())
parent()->removeChild(*this);
WindowManager::the().removeWindow(*this); WindowManager::the().removeWindow(*this);
} }
@ -96,6 +100,11 @@ bool Window::isActive() const
return WindowManager::the().activeWindow() == this; return WindowManager::the().activeWindow() == this;
} }
bool Window::isVisible() const
{
return WindowManager::the().isVisible(const_cast<Window&>(*this));
}
void Window::setFocusedWidget(Widget* widget) void Window::setFocusedWidget(Widget* widget)
{ {
if (m_focusedWidget.ptr() == widget) if (m_focusedWidget.ptr() == widget)
@ -113,5 +122,7 @@ void Window::setFocusedWidget(Widget* widget)
void Window::close() void Window::close()
{ {
WindowManager::the().removeWindow(*this);
deleteLater();
} }

View file

@ -22,9 +22,11 @@ public:
const Rect& rect() const { return m_rect; } const Rect& rect() const { return m_rect; }
void setRect(const Rect&); void setRect(const Rect&);
void setRectWithoutRepaint(const Rect& rect) { m_rect = rect; }
Point position() const { return m_rect.location(); } Point position() const { return m_rect.location(); }
void setPosition(const Point& position) { setRect({ position.x(), position.y(), width(), height() }); } 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; } Widget* mainWidget() { return m_mainWidget; }
const Widget* mainWidget() const { return m_mainWidget; } const Widget* mainWidget() const { return m_mainWidget; }
@ -44,6 +46,8 @@ public:
const Widget* focusedWidget() const { return m_focusedWidget.ptr(); } const Widget* focusedWidget() const { return m_focusedWidget.ptr(); }
void setFocusedWidget(Widget*); void setFocusedWidget(Widget*);
bool isVisible() const;
void close(); void close();
private: private:

View file

@ -126,22 +126,32 @@ void WindowManager::addWindow(Window& window)
setActiveWindow(&window); setActiveWindow(&window);
} }
void WindowManager::repaint()
{
handlePaintEvent(*make<PaintEvent>());
}
void WindowManager::removeWindow(Window& window) void WindowManager::removeWindow(Window& window)
{ {
ASSERT(m_windows.contains(&window)); if (!m_windows.contains(&window))
return;
m_windows.remove(&window); m_windows.remove(&window);
if (!activeWindow() && !m_windows.isEmpty()) if (!activeWindow() && !m_windows.isEmpty())
setActiveWindow(*m_windows.begin()); setActiveWindow(*m_windows.begin());
repaint();
} }
void WindowManager::notifyTitleChanged(Window& window) 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) 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) void WindowManager::handleTitleBarMouseEvent(Window& window, MouseEvent& event)
@ -205,7 +215,7 @@ void WindowManager::processMouseEvent(MouseEvent& event)
Point pos = m_dragWindowOrigin; Point pos = m_dragWindowOrigin;
printf("[WM] Dragging [origin: %d,%d] now: %d,%d\n", m_dragOrigin.x(), m_dragOrigin.y(), event.x(), event.y()); 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()); pos.moveBy(event.x() - m_dragOrigin.x(), event.y() - m_dragOrigin.y());
m_dragWindow->setPosition(pos); m_dragWindow->setPositionWithoutRepaint(pos);
paintWindowFrame(*m_dragWindow); paintWindowFrame(*m_dragWindow);
return; return;
} }
@ -243,9 +253,8 @@ void WindowManager::handlePaintEvent(PaintEvent& event)
m_rootWidget->event(event); m_rootWidget->event(event);
paintWindowFrames(); paintWindowFrames();
for (auto* window : m_windows) { for (auto* window : m_windows)
window->event(event); window->event(event);
}
} }
void WindowManager::event(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);
}

View file

@ -27,6 +27,10 @@ public:
Window* activeWindow() { return m_activeWindow.ptr(); } Window* activeWindow() { return m_activeWindow.ptr(); }
void setActiveWindow(Window*); void setActiveWindow(Window*);
bool isVisible(Window&) const;
void repaint();
private: private:
WindowManager(); WindowManager();
~WindowManager(); ~WindowManager();

View file

@ -86,6 +86,7 @@ int main(int argc, char** argv)
tb->onReturnPressed = [] (TextBox& textBox) { tb->onReturnPressed = [] (TextBox& textBox) {
printf("TextBox %p return pressed: '%s'\n", &textBox, textBox.text().characters()); printf("TextBox %p return pressed: '%s'\n", &textBox, textBox.text().characters());
MsgBox(nullptr, textBox.text());
}; };
WindowManager::the().setActiveWindow(widgetTestWindow); WindowManager::the().setActiveWindow(widgetTestWindow);