diff --git a/panda/src/glxdisplay/glxGraphicsWindow.cxx b/panda/src/glxdisplay/glxGraphicsWindow.cxx index c832cd6062..63c253d8ab 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.cxx +++ b/panda/src/glxdisplay/glxGraphicsWindow.cxx @@ -49,6 +49,7 @@ glxGraphicsWindow(GraphicsPipe *pipe) : _xwindow = (Window)0; _context = (GLXContext)0; _visual = (XVisualInfo *)NULL; + _awaiting_configure = false; GraphicsWindowInputDevice device = GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse"); @@ -120,6 +121,26 @@ make_current() { glXMakeCurrent(_display, _xwindow, _context); } +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsWindow::begin_frame +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// before beginning rendering for a given frame. It +// should do whatever setup is required, and return true +// if the frame should be rendered, or false if it +// should be skipped. +//////////////////////////////////////////////////////////////////// +bool glxGraphicsWindow:: +begin_frame() { + if (_awaiting_configure) { + // Don't attempt to draw while we have just reconfigured the + // window and we haven't got the notification back yet. + return false; + } + + return GraphicsWindow::begin_frame(); +} + //////////////////////////////////////////////////////////////////// // Function: glxGraphicsWindow::begin_flip // Access: Public, Virtual @@ -170,6 +191,7 @@ process_events() { break; case ConfigureNotify: + _awaiting_configure = false; properties.set_size(event.xconfigure.width, event.xconfigure.height); system_changed_properties(properties); break; @@ -282,7 +304,10 @@ set_properties_now(WindowProperties &properties) { } // The window is already open; we are limited to what we can change - // on the fly. This appears to be just the window title. + // on the fly. + + // The window title may be changed by issuing another hint request. + // Assume this will be honored. if (properties.has_title()) { WindowProperties wm_properties; wm_properties.set_title(properties.get_title()); @@ -290,6 +315,33 @@ set_properties_now(WindowProperties &properties) { set_wm_properties(wm_properties); properties.clear_title(); } + + // The size and position of an already-open window are changed via + // explicit X calls. These may still get intercepted by the window + // manager. Rather than changing _properties immediately, we'll + // wait for the ConfigureNotify message to come back. + XWindowChanges changes; + int value_mask = 0; + + if (properties.has_origin()) { + changes.x = properties.get_x_origin(); + changes.y = properties.get_y_origin(); + value_mask |= (CWX | CWY); + properties.clear_origin(); + } + if (properties.has_size()) { + changes.width = properties.get_x_size(); + changes.height = properties.get_y_size(); + value_mask |= (CWWidth | CWHeight); + properties.clear_size(); + } + + if (value_mask != 0) { + XConfigureWindow(_display, _xwindow, value_mask, &changes); + + // Don't draw anything until this is done reconfiguring. + _awaiting_configure = true; + } } //////////////////////////////////////////////////////////////////// @@ -436,7 +488,7 @@ set_wm_properties(const WindowProperties &properties) { // Class to "Undecorated", and let the user configure his/her window // manager not to put a border around windows of this class. XClassHint *class_hints_p = NULL; - if (properties.has_undecorated() && properties.get_undecorated()) { + if (properties.get_undecorated()) { class_hints_p = XAllocClassHint(); class_hints_p->res_class = "Undecorated"; } diff --git a/panda/src/glxdisplay/glxGraphicsWindow.h b/panda/src/glxdisplay/glxGraphicsWindow.h index 26894a4143..e940e9ef76 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.h +++ b/panda/src/glxdisplay/glxGraphicsWindow.h @@ -43,6 +43,7 @@ public: virtual void release_gsg(); virtual void make_current(); + virtual bool begin_frame(); virtual void begin_flip(); virtual void process_events(); @@ -69,6 +70,7 @@ private: XVisualInfo *_visual; Colormap _colormap; long _event_mask; + bool _awaiting_configure; public: