From 4ece938f1c968907920b829419cd257fdf3eb0f1 Mon Sep 17 00:00:00 2001 From: hippoz <10706925-hippoz@users.noreply.gitlab.com> Date: Fri, 18 Mar 2022 22:07:32 +0200 Subject: [PATCH] Respond to resize events properly Previously, we used to not respond to resize events. Additionally, resizing the window would cause flickering to appear in the area where painting would happen. This patch fixes both of those issues. --- src/Window.cpp | 39 ++++++++++++++++++++++++++++++++++----- src/Window.hpp | 2 ++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/Window.cpp b/src/Window.cpp index 7473856..49cc71a 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -28,19 +28,32 @@ bool Window::spawn_window() { m_x_display = dsp; int screen = DefaultScreen(dsp); - Drawable da = XCreateSimpleWindow(dsp, DefaultRootWindow(dsp), 0, 0, m_current_geometry.get_width(), m_current_geometry.get_height(), 0, 0, 0); + Drawable da = XCreateWindow( + dsp, + DefaultRootWindow(dsp), + 0, + 0, + m_current_geometry.get_width(), + m_current_geometry.get_height(), + 0, + 0, + CopyFromParent, + CopyFromParent, + 0, + NULL + ); XSelectInput(dsp, da, ButtonPressMask | ButtonReleaseMask | KeyPressMask | PointerMotionMask | StructureNotifyMask | ExposureMask); XMapWindow(dsp, da); - auto cairo_xlib_surface = Cairo::XlibSurface::create( + m_xlib_surface = Cairo::XlibSurface::create( dsp, da, DefaultVisual(dsp, screen), get_current_geometry().get_width(), get_current_geometry().get_height() ); - auto cairo_context = Cairo::Context::create(cairo_xlib_surface); + auto cairo_context = Cairo::Context::create(m_xlib_surface); m_painter.set_cairo(cairo_context); @@ -78,9 +91,25 @@ void Window::run(bool block) { dispatch_full_repaint(); break; } + case ConfigureNotify: { + if (e.xconfigure.width != m_current_geometry.get_width() || e.xconfigure.height != m_current_geometry.get_height()) { + m_xlib_surface->set_size(e.xconfigure.width, e.xconfigure.height); + m_current_geometry.set_width(e.xconfigure.width); + m_current_geometry.set_height(e.xconfigure.height); + // if we have a main widget, we are going to have to resize it as well + if (m_main_widget) { + m_main_widget->get_current_geometry().set_width(m_current_geometry.get_width()); + m_main_widget->get_current_geometry().set_height(m_current_geometry.get_height()); + } + dispatch_full_repaint(); + } + break; + } case Expose: { - auto box = Box(e.xexpose.x, e.xexpose.y, e.xexpose.width, e.xexpose.height); - dispatch_repaint_on_box(std::move(box)); + if (e.xexpose.count == 0) { + auto box = Box(e.xexpose.x, e.xexpose.y, e.xexpose.width, e.xexpose.height); + dispatch_repaint_on_box(std::move(box)); + } break; } case MotionNotify: { diff --git a/src/Window.hpp b/src/Window.hpp index 36f093e..f4a652f 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -4,6 +4,7 @@ #include "Widget.hpp" #include "Painter.hpp" #include +#include namespace Raven { @@ -14,6 +15,7 @@ private: Box m_current_geometry { 0, 0, 800, 600 }; Painter m_painter {}; std::shared_ptr m_top_level_styles = std::make_shared(this); + Cairo::RefPtr m_xlib_surface { nullptr }; Display *m_x_display { nullptr }; public: