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:
parent
3ebea05996
commit
959a1b0750
Notes:
sideshowbarker
2024-07-19 18:48:35 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/959a1b07503
9 changed files with 65 additions and 9 deletions
|
@ -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()
|
||||
|
|
|
@ -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>());
|
||||
}
|
||||
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,10 @@ public:
|
|||
Window* activeWindow() { return m_activeWindow.ptr(); }
|
||||
void setActiveWindow(Window*);
|
||||
|
||||
bool isVisible(Window&) const;
|
||||
|
||||
void repaint();
|
||||
|
||||
private:
|
||||
WindowManager();
|
||||
~WindowManager();
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue