More window manager hacking. FocusIn/FocusOut events.

This commit is contained in:
Andreas Kling 2019-01-09 05:38:13 +01:00
parent 7577ee0c67
commit ceb373cf71
8 changed files with 20 additions and 22 deletions

View file

@ -65,9 +65,9 @@ public:
bool is_null() const { return !m_impl; } bool is_null() const { return !m_impl; }
bool is_empty() const { return length() == 0; } bool is_empty() const { return length() == 0; }
unsigned length() const { return m_impl ? m_impl->length() : 0; } size_t length() const { return m_impl ? m_impl->length() : 0; }
const char* characters() const { return m_impl ? m_impl->characters() : nullptr; } const char* characters() const { return m_impl ? m_impl->characters() : nullptr; }
char operator[](unsigned i) const { ASSERT(m_impl); return (*m_impl)[i]; } char operator[](size_t i) const { ASSERT(m_impl); return (*m_impl)[i]; }
bool operator==(const String&) const; bool operator==(const String&) const;
bool operator!=(const String& other) const { return !(*this == other); } bool operator!=(const String& other) const { return !(*this == other); }

View file

@ -37,6 +37,8 @@ public:
DeferredDestroy, DeferredDestroy,
WindowBecameInactive, WindowBecameInactive,
WindowBecameActive, WindowBecameActive,
FocusIn,
FocusOut,
}; };
Event() { } Event() { }

View file

@ -18,13 +18,6 @@ RootWidget::~RootWidget()
void RootWidget::paintEvent(PaintEvent& event) void RootWidget::paintEvent(PaintEvent& event)
{ {
Widget::paintEvent(event);
printf("RootWidget::paintEvent: %d,%d %dx%d\n",
event.rect().x(),
event.rect().y(),
event.rect().width(),
event.rect().height());
Painter painter(*this); Painter painter(*this);
painter.fillRect(event.rect(), Color(0, 72, 96)); painter.fillRect(event.rect(), Color(0, 72, 96));
} }

View file

@ -35,13 +35,13 @@ void TextBox::paintEvent(PaintEvent&)
Rect innerRect = rect(); Rect innerRect = rect();
innerRect.shrink(6, 6); innerRect.shrink(6, 6);
unsigned maxCharsToPaint = innerRect.width() / font().glyphWidth(); size_t maxCharsToPaint = innerRect.width() / font().glyphWidth();
int firstVisibleChar = max((int)m_cursorPosition - (int)maxCharsToPaint, 0); int firstVisibleChar = max((int)m_cursorPosition - (int)maxCharsToPaint, 0);
unsigned charsToPaint = min(m_text.length() - firstVisibleChar, maxCharsToPaint); size_t charsToPaint = min(m_text.length() - firstVisibleChar, maxCharsToPaint);
int y = innerRect.center().y() - font().glyphHeight() / 2; int y = innerRect.center().y() - font().glyphHeight() / 2;
for (unsigned i = 0; i < charsToPaint; ++i) { for (size_t i = 0; i < charsToPaint; ++i) {
char ch = m_text[firstVisibleChar + i]; char ch = m_text[firstVisibleChar + i];
if (ch == ' ') if (ch == ' ')
continue; continue;

View file

@ -37,13 +37,13 @@ void Widget::event(Event& event)
{ {
switch (event.type()) { switch (event.type()) {
case Event::Paint: case Event::Paint:
m_hasPendingPaintEvent = false;
if (auto* win = window()) { if (auto* win = window()) {
if (win->isBeingDragged()) if (win->isBeingDragged())
return; return;
if (!win->isVisible()) if (!win->isVisible())
return; return;
} }
m_hasPendingPaintEvent = false;
return paintEvent(static_cast<PaintEvent&>(event)); return paintEvent(static_cast<PaintEvent&>(event));
case Event::Show: case Event::Show:
return showEvent(static_cast<ShowEvent&>(event)); return showEvent(static_cast<ShowEvent&>(event));
@ -77,7 +77,7 @@ void Widget::paintEvent(PaintEvent& event)
} }
for (auto* ch : children()) { for (auto* ch : children()) {
auto* child = (Widget*)ch; auto* child = (Widget*)ch;
child->paintEvent(event); child->event(event);
} }
} }
@ -117,7 +117,7 @@ void Widget::update()
if (m_hasPendingPaintEvent) if (m_hasPendingPaintEvent)
return; return;
m_hasPendingPaintEvent = true; m_hasPendingPaintEvent = true;
EventLoop::main().postEvent(w, make<PaintEvent>(rect())); EventLoop::main().postEvent(w, make<PaintEvent>(relativeRect()));
} }
Widget::HitTestResult Widget::hitTest(int x, int y) Widget::HitTestResult Widget::hitTest(int x, int y)

View file

@ -74,7 +74,7 @@ void Window::event(Event& event)
if (event.isPaintEvent()) { if (event.isPaintEvent()) {
auto& pe = static_cast<PaintEvent&>(event); auto& pe = static_cast<PaintEvent&>(event);
printf("Window[\"%s\"]: paintEvent %d,%d %dx%d\n", class_name(), printf("Window[\"%s\"]: paintEvent %d,%d %dx%d\n", title().characters(),
pe.rect().x(), pe.rect().x(),
pe.rect().y(), pe.rect().y(),
pe.rect().width(), pe.rect().width(),
@ -123,15 +123,15 @@ void Window::setFocusedWidget(Widget* widget)
{ {
if (m_focusedWidget.ptr() == widget) if (m_focusedWidget.ptr() == widget)
return; return;
auto* previouslyFocusedWidget = m_focusedWidget.ptr(); auto* previously_focused_widget = m_focusedWidget.ptr();
if (!widget) { if (!widget)
m_focusedWidget = nullptr; m_focusedWidget = nullptr;
} else { else {
m_focusedWidget = widget->makeWeakPtr(); m_focusedWidget = widget->makeWeakPtr();
m_focusedWidget->repaint(Rect()); EventLoop::main().postEvent(m_focusedWidget.ptr(), make<Event>(Event::FocusIn));
} }
if (previouslyFocusedWidget) if (previously_focused_widget)
previouslyFocusedWidget->repaint(Rect()); EventLoop::main().postEvent(previously_focused_widget, make<Event>(Event::FocusOut));
} }
void Window::close() void Window::close()

View file

@ -139,6 +139,7 @@ void WindowManager::did_paint(Window& window)
if (m_windows_in_order.tail() == &window) { if (m_windows_in_order.tail() == &window) {
ASSERT(window.backing()); ASSERT(window.backing());
framebuffer.blit(window.position(), *window.backing()); framebuffer.blit(window.position(), *window.backing());
framebuffer.flush();
printf("[WM] frontmost_only_compose_count: %u\n", ++m_frontmost_only_compose_count); printf("[WM] frontmost_only_compose_count: %u\n", ++m_frontmost_only_compose_count);
return; return;
} }

View file

@ -100,10 +100,12 @@ int main(int argc, char** argv)
win->setMainWidget(t); win->setMainWidget(t);
t->setFocus(true); t->setFocus(true);
#if 0
auto* clockWin = new Window; auto* clockWin = new Window;
clockWin->setTitle("Clock"); clockWin->setTitle("Clock");
clockWin->setRect({ 500, 50, 100, 40 }); clockWin->setRect({ 500, 50, 100, 40 });
clockWin->setMainWidget(new ClockWidget); clockWin->setMainWidget(new ClockWidget);
#endif
MsgBox(nullptr, "This is a message box!"); MsgBox(nullptr, "This is a message box!");