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:
parent
3ebea05996
commit
959a1b0750
9 changed files with 65 additions and 9 deletions
|
@ -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()
|
||||||
|
|
|
@ -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>());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue