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.
This commit is contained in:
hippoz 2022-03-18 22:07:32 +02:00
parent 4a398f7a7b
commit 4ece938f1c
No known key found for this signature in database
GPG key ID: 7C52899193467641
2 changed files with 36 additions and 5 deletions

View file

@ -28,19 +28,32 @@ bool Window::spawn_window() {
m_x_display = dsp; m_x_display = dsp;
int screen = DefaultScreen(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); XSelectInput(dsp, da, ButtonPressMask | ButtonReleaseMask | KeyPressMask | PointerMotionMask | StructureNotifyMask | ExposureMask);
XMapWindow(dsp, da); XMapWindow(dsp, da);
auto cairo_xlib_surface = Cairo::XlibSurface::create( m_xlib_surface = Cairo::XlibSurface::create(
dsp, dsp,
da, da,
DefaultVisual(dsp, screen), DefaultVisual(dsp, screen),
get_current_geometry().get_width(), get_current_geometry().get_width(),
get_current_geometry().get_height() 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); m_painter.set_cairo(cairo_context);
@ -78,9 +91,25 @@ void Window::run(bool block) {
dispatch_full_repaint(); dispatch_full_repaint();
break; 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: { case Expose: {
auto box = Box(e.xexpose.x, e.xexpose.y, e.xexpose.width, e.xexpose.height); if (e.xexpose.count == 0) {
dispatch_repaint_on_box(std::move(box)); auto box = Box(e.xexpose.x, e.xexpose.y, e.xexpose.width, e.xexpose.height);
dispatch_repaint_on_box(std::move(box));
}
break; break;
} }
case MotionNotify: { case MotionNotify: {

View file

@ -4,6 +4,7 @@
#include "Widget.hpp" #include "Widget.hpp"
#include "Painter.hpp" #include "Painter.hpp"
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <cairomm/xlib_surface.h>
namespace Raven { namespace Raven {
@ -14,6 +15,7 @@ private:
Box m_current_geometry { 0, 0, 800, 600 }; Box m_current_geometry { 0, 0, 800, 600 };
Painter m_painter {}; Painter m_painter {};
std::shared_ptr<TopLevelStyles> m_top_level_styles = std::make_shared<TopLevelStyles>(this); std::shared_ptr<TopLevelStyles> m_top_level_styles = std::make_shared<TopLevelStyles>(this);
Cairo::RefPtr<Cairo::XlibSurface> m_xlib_surface { nullptr };
Display *m_x_display { nullptr }; Display *m_x_display { nullptr };
public: public: