فهرست منبع

attempt to make better support for fullscreen, undecorated windows

David Rose 20 سال پیش
والد
کامیت
4d2ff22278

+ 0 - 11
panda/src/glxdisplay/glxGraphicsPipe.I

@@ -61,17 +61,6 @@ get_im() const {
   return _im;
   return _im;
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: glxGraphicsPipe::get_wm_delete_window
-//       Access: Public
-//  Description: Returns the X atom that represents WM_DELETE_WINDOW
-//               to the current display.
-////////////////////////////////////////////////////////////////////
-INLINE Atom glxGraphicsPipe::
-get_wm_delete_window() const {
-  return _wm_delete_window;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: glxGraphicsPipe::get_hidden_cursor
 //     Function: glxGraphicsPipe::get_hidden_cursor
 //       Access: Public
 //       Access: Public

+ 4 - 1
panda/src/glxdisplay/glxGraphicsPipe.cxx

@@ -115,8 +115,11 @@ glxGraphicsPipe(const string &display) {
   XFree(im_supported_styles);
   XFree(im_supported_styles);
   */
   */
 
 
-  // Get the X atom number.
+  // Get some X atom numbers.
   _wm_delete_window = XInternAtom(_display, "WM_DELETE_WINDOW", false);
   _wm_delete_window = XInternAtom(_display, "WM_DELETE_WINDOW", false);
+  _net_wm_window_type = XInternAtom(_display, "_NET_WM_WINDOW_TYPE", false);
+  _net_wm_window_type_splash = XInternAtom(_display, "_NET_WM_WINDOW_TYPE_SPLASH", false);
+  _net_wm_window_type_fullscreen = XInternAtom(_display, "_NET_WM_WINDOW_TYPE_FULLSCREEN", false);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 7 - 4
panda/src/glxdisplay/glxGraphicsPipe.h

@@ -101,10 +101,15 @@ public:
   INLINE Window get_root() const;
   INLINE Window get_root() const;
   INLINE XIM get_im() const;
   INLINE XIM get_im() const;
 
 
-  INLINE Atom get_wm_delete_window() const;
-
   INLINE Cursor get_hidden_cursor();
   INLINE Cursor get_hidden_cursor();
 
 
+public:
+  // Atom specifications.
+  Atom _wm_delete_window;
+  Atom _net_wm_window_type;
+  Atom _net_wm_window_type_splash;
+  Atom _net_wm_window_type_fullscreen;
+
 protected:
 protected:
   virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
   virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
                                              GraphicsStateGuardian *share_with);
                                              GraphicsStateGuardian *share_with);
@@ -145,8 +150,6 @@ private:
   Window _root;
   Window _root;
   XIM _im;
   XIM _im;
 
 
-  Atom _wm_protocols;
-  Atom _wm_delete_window;
   Cursor _hidden_cursor;
   Cursor _hidden_cursor;
 
 
   typedef int ErrorHandlerFunc(Display *, XErrorEvent *);
   typedef int ErrorHandlerFunc(Display *, XErrorEvent *);

+ 32 - 9
panda/src/glxdisplay/glxGraphicsWindow.cxx

@@ -34,6 +34,7 @@
 #include <sys/time.h>
 #include <sys/time.h>
 #include <X11/keysym.h>
 #include <X11/keysym.h>
 #include <X11/Xutil.h>
 #include <X11/Xutil.h>
+#include <X11/Xatom.h>
 
 
 TypeHandle glxGraphicsWindow::_type_handle;
 TypeHandle glxGraphicsWindow::_type_handle;
 
 
@@ -54,7 +55,10 @@ glxGraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
   _xwindow = (Window)NULL;
   _xwindow = (Window)NULL;
   _ic = (XIC)NULL;
   _ic = (XIC)NULL;
   _awaiting_configure = false;
   _awaiting_configure = false;
-  _wm_delete_window = glx_pipe->get_wm_delete_window();
+  _wm_delete_window = glx_pipe->_wm_delete_window;
+  _net_wm_window_type = glx_pipe->_net_wm_window_type;
+  _net_wm_window_type_splash = glx_pipe->_net_wm_window_type_splash;
+  _net_wm_window_type_fullscreen = glx_pipe->_net_wm_window_type_fullscreen;
 
 
   GraphicsWindowInputDevice device =
   GraphicsWindowInputDevice device =
     GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse");
     GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse");
@@ -506,11 +510,6 @@ close_window() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool glxGraphicsWindow::
 bool glxGraphicsWindow::
 open_window() {
 open_window() {
-  if (_properties.get_fullscreen()) {
-    // We don't support fullscreen windows.
-    return false;
-  }
-
   glxGraphicsPipe *glx_pipe;
   glxGraphicsPipe *glx_pipe;
   DCAST_INTO_R(glx_pipe, _pipe, false);
   DCAST_INTO_R(glx_pipe, _pipe, false);
   glxGraphicsStateGuardian *glxgsg;
   glxGraphicsStateGuardian *glxgsg;
@@ -660,15 +659,39 @@ set_wm_properties(const WindowProperties &properties) {
     wm_hints_p->flags = StateHint;
     wm_hints_p->flags = StateHint;
   }
   }
 
 
-  // If we asked for a window without a border, there's no good way to
-  // arrange that.  It completely depends on the user's window manager
-  // of choice.  Instead, we'll totally punt and just set the window's
+  // If we asked for a window without a border, there's no excellent
+  // way to arrange that.  For users whose window managers follow the
+  // EWMH specification, we can ask for a "splash" screen, which is
+  // usually undecorated.  It's not exactly right, but the spec
+  // doesn't give us an exactly-right option.
+
+  // For other users, we'll totally punt and just set the window's
   // Class to "Undecorated", and let the user configure his/her window
   // Class to "Undecorated", and let the user configure his/her window
   // manager not to put a border around windows of this class.
   // manager not to put a border around windows of this class.
   XClassHint *class_hints_p = NULL;
   XClassHint *class_hints_p = NULL;
   if (properties.get_undecorated()) {
   if (properties.get_undecorated()) {
     class_hints_p = XAllocClassHint();
     class_hints_p = XAllocClassHint();
     class_hints_p->res_class = "Undecorated";
     class_hints_p->res_class = "Undecorated";
+
+    long data[2];
+    data[0] = _net_wm_window_type_splash;
+    data[1] = None;
+
+    XChangeProperty(_display, _xwindow, _net_wm_window_type,
+                    XA_ATOM, 32, PropModeReplace,
+                    (unsigned char *)data, 1);
+  }
+
+  if (properties.get_fullscreen()) {
+    // For a "fullscreen" request, we pass this through, hoping the
+    // window manager will support EWMH.
+    long data[2];
+    data[0] = _net_wm_window_type_fullscreen;
+    data[1] = None;
+
+    XChangeProperty(_display, _xwindow, _net_wm_window_type,
+                    XA_ATOM, 32, PropModeReplace,
+                    (unsigned char *)data, 1);
   }
   }
 
 
   XSetWMProperties(_display, _xwindow, window_name_p, window_name_p,
   XSetWMProperties(_display, _xwindow, window_name_p, window_name_p,

+ 3 - 1
panda/src/glxdisplay/glxGraphicsWindow.h

@@ -77,7 +77,9 @@ private:
   long _event_mask;
   long _event_mask;
   bool _awaiting_configure;
   bool _awaiting_configure;
   Atom _wm_delete_window;
   Atom _wm_delete_window;
-
+  Atom _net_wm_window_type;
+  Atom _net_wm_window_type_splash;
+  Atom _net_wm_window_type_fullscreen;
 
 
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {