Hi!

The diff below fixes fullscreen mode on window managers that prevent
applications from resizing their windows.  This is done by setting
_NET_WM_STATE_FULLSCREEN atom.

--
Dmitrij D. Czarkoff

Index: video.c
===================================================================
RCS file: /var/cvs/xenocara/app/video/video.c,v
retrieving revision 1.19
diff -u -p -r1.19 video.c
--- video.c     6 Jun 2016 19:31:22 -0000       1.19
+++ video.c     18 Sep 2016 21:33:29 -0000
@@ -160,6 +160,7 @@ struct video {
        int              conv_type;
        int              enc;
        int              full_screen;
+       int              net_wm;
        int              width;
        int              height;
        int              bpf;
@@ -178,6 +179,7 @@ int xv_get_info(struct video *);
 int xv_sel_adap(struct video *);
 void xv_dump_info(struct video *);
 int xv_init(struct video *);
+void net_wm_supported(struct video *);
 void resize_window(struct video *, int);
 void display_event(struct video *);
 
@@ -500,34 +502,84 @@ xv_init(struct video *vid)
 }
 
 void
+net_wm_supported(struct video *vid)
+{
+       struct xdsp *x = &vid->xdsp;
+       Atom query, fullscreen;
+       Atom type;
+       Atom *data;
+       long off;
+       int fmt, len = 12;
+       unsigned long nitems, remain;
+       int i;
+
+       query = XInternAtom(x->dpy, "_NET_SUPPORTED", True);
+       fullscreen = XInternAtom(x->dpy, "_NET_WM_STATE_FULLSCREEN", True);
+
+       for (off = 0; XGetWindowProperty(x->dpy, x->rwin, query, off,
+                         len, False, XA_ATOM, &type, &fmt, &nitems, &remain,
+                         (unsigned char **)&data) == Success; off += len) {
+               if (type == XA_ATOM && fmt == 32) {
+                       for (i = 0; i < nitems; i++) {
+                               if (data[i] == fullscreen) {
+                                       vid->net_wm = 1;
+                                       XFree(data);
+                                       return;
+                               }
+                       }
+               }
+               XFree(data);
+       }
+
+       return;
+}
+
+void
 resize_window(struct video *vid, int fullscreen)
 {
        struct xdsp *x = &vid->xdsp;
        XWindowAttributes winatt;
        Window junk;
-       int new_width;
-       int new_height;
        int new_x;
        int new_y;
+       XEvent ev;
+       Atom property, value;
 
        if (fullscreen == 1) {
                if (vid->full_screen == 1) {
-                       new_width = x->saved_w;
-                       new_height = x->saved_h;
+                       x->width = x->saved_w;
+                       x->height = x->saved_h;
                        new_x = x->saved_x;
                        new_y = x->saved_y;
-                       vid->full_screen = 0;
                } else {
-                       new_width = x->max_width;
-                       new_height = x->max_height;
+                       x->width = x->max_width;
+                       x->height = x->max_height;
                        new_x = 0;
                        new_y = 0;
-                       vid->full_screen = 1;
                }
-               x->width = new_width;
-               x->height = new_height;
-               XMoveResizeWindow(x->dpy, x->window, new_x, new_y,
-                   new_width, new_height);
+
+               vid->full_screen = !vid->full_screen;
+
+               if (vid->net_wm) {
+                       property = XInternAtom(x->dpy, "_NET_WM_STATE", False);
+                       value = XInternAtom(x->dpy, "_NET_WM_STATE_FULLSCREEN",
+                           False);
+
+                       memset(&ev, 0, sizeof(ev));
+                       ev.type = ClientMessage;
+                       ev.xclient.window = x->window;
+                       ev.xclient.message_type = property;
+                       ev.xclient.format = 32;
+                       ev.xclient.data.l[0] = vid->full_screen;
+                       ev.xclient.data.l[1] = value;
+
+                       XSendEvent(x->dpy, x->rwin, False,
+                           SubstructureNotifyMask | SubstructureRedirectMask,
+                           &ev);
+               } else {
+                       XMoveResizeWindow(x->dpy, x->window, x->width,
+                           x->height, new_x, new_y);
+               }
        } else if (!vid->full_screen) {
                XGetWindowAttributes(x->dpy, x->window, &winatt);
                XTranslateCoordinates(x->dpy, x->window, x->rwin,
@@ -536,8 +588,8 @@ resize_window(struct video *vid, int ful
                x->saved_h = x->height = winatt.height;
                x->saved_x = new_x;
                x->saved_y = new_y;
-               XResizeWindow(x->dpy, x->window, x->width, x->height);
        }
+
        XSync(x->dpy, False);
        XSync(x->dpy, True);
 }
@@ -1435,6 +1487,9 @@ setup(struct video *vid)
                if (!mmap_init(vid))
                        return 0;
        }
+
+       if (vid->mode & M_OUT_XV)
+               net_wm_supported(vid);
 
        return 1;
 }

Reply via email to