ecere/gui/drivers/X11: (#700) Time out on _NET_REQUEST_FRAME_EXTENTS
[sdk] / ecere / src / gui / drivers / XInterface.ec
index 668c1ff..a9d9d70 100644 (file)
@@ -1,7 +1,7 @@
 namespace gui::drivers;
 
 import "instance"
-#if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
+#if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D) && !defined(ECERE_NOGL)
 import "OpenGLDisplayDriver"
 #endif
 
@@ -18,12 +18,9 @@ default:
 #include <linux/joystick.h>
 #endif
 #include <sys/param.h>
-#ifdef BSD
 #include <stdlib.h>
-#else
-#include <malloc.h>
-#endif
 #include <unistd.h>
+#include <sys/select.h>
 
 //#include <stdio.h>
 //#include <stdlib.h>
@@ -43,8 +40,10 @@ default:
 #include <X11/Xutil.h>
 #include <X11/XKBlib.h>
 #include <X11/keysym.h>
-#include <sys/fcntl.h>
+#include <fcntl.h>
+#if !defined(ECERE_NO3D) && !defined(ECERE_NOGL)
 #include <GL/glx.h>
+#endif
 #include <X11/extensions/Xrender.h>
 #include <X11/extensions/XShm.h>
 
@@ -103,7 +102,7 @@ static enum AtomIdents
    _net_wm_window_type_desktop, _net_wm_window_type_dialog, _net_wm_window_type_dock, _net_wm_window_type_dropdown_menu,
    _net_wm_window_type_menu, _net_wm_window_type_normal, _net_wm_window_type_popup_menu, _net_wm_window_type_splash,
    _net_wm_window_type_toolbar, _net_wm_window_type_utility, _net_workarea, _net_frame_extents, _net_request_frame_extents,
-   _net_wm_state_maximized_vert, _net_wm_state_maximized_horz, app_selection
+   _net_wm_state_maximized_vert, _net_wm_state_maximized_horz, _net_wm_state_modal, app_selection
 };
 
 static Atom atoms[AtomIdents];
@@ -147,8 +146,22 @@ static const char *atomNames[AtomIdents] = {
    "_NET_REQUEST_FRAME_EXTENTS", // _net_request_frame_extents
    "_NET_WM_STATE_MAXIMIZED_VERT", // _net_wm_state_maximized_vert
    "_NET_WM_STATE_MAXIMIZED_HORZ", // _net_wm_state_maximized_horz
+   "_NET_WM_STATE_MODAL", // _net_wm_state_modal
    "APP_SELECTION"
 };
+/*
+_NET_WM_STATE_STICKY, ATOM
+_NET_WM_STATE_MAXIMIZED_VERT, ATOM
+_NET_WM_STATE_MAXIMIZED_HORZ, ATOM
+_NET_WM_STATE_SHADED, ATOM
+_NET_WM_STATE_SKIP_TASKBAR, ATOM
+_NET_WM_STATE_SKIP_PAGER, ATOM
+_NET_WM_STATE_HIDDEN, ATOM
+_NET_WM_STATE_FULLSCREEN, ATOM
+_NET_WM_STATE_ABOVE, ATOM
+_NET_WM_STATE_BELOW, ATOM
+_NET_WM_STATE_DEMANDS_ATTENTION, ATOM
+*/
 
 static bool autoRepeatDetectable;
 static bool setICPosition;
@@ -175,7 +188,10 @@ bool XGetBorderWidths(Window window, Box box)
    XWindowData windowData = window.windowData;
    if(windowData)
    {
-      box = windowData.decor;
+      if(window.state == maximized)
+         box = { 0, 0, 0, 0 };
+      else
+         box = windowData.decor;
       return true;
    }
    return false;
@@ -210,21 +226,6 @@ static Visual * FindFullColorVisual(X11Display *dpy, int * depth)
    } 
    return null;
 }
-/*
-_NET_WM_STATE_MODAL, ATOM
-_NET_WM_STATE_STICKY, ATOM
-_NET_WM_STATE_MAXIMIZED_VERT, ATOM
-_NET_WM_STATE_MAXIMIZED_HORZ, ATOM
-_NET_WM_STATE_SHADED, ATOM
-_NET_WM_STATE_SKIP_TASKBAR, ATOM
-_NET_WM_STATE_SKIP_PAGER, ATOM
-_NET_WM_STATE_HIDDEN, ATOM
-_NET_WM_STATE_FULLSCREEN, ATOM
-_NET_WM_STATE_ABOVE, ATOM
-_NET_WM_STATE_BELOW, ATOM
-_NET_WM_STATE_DEMANDS_ATTENTION, ATOM
-*/
-
 
 static void RepositionDesktop(bool updateChildren)
 {
@@ -237,6 +238,11 @@ static void RepositionDesktop(bool updateChildren)
    int format;
    unsigned long len, fill;
    Atom type;
+   static double lastTime = 0, time;
+
+   time = GetTime();
+   if(desktopW && desktopH && time - lastTime < 1.5) return;
+   lastTime = time;
 
    w = XDisplayWidth(xGlobalDisplay, DefaultScreen(xGlobalDisplay));
    h = XDisplayHeight(xGlobalDisplay, DefaultScreen(xGlobalDisplay));
@@ -254,7 +260,7 @@ static void RepositionDesktop(bool updateChildren)
       if(data)
       {
          int desktops = 0;
-         desktops = *(long *)data;
+         desktops = (int)*(long *)data;
 
          //printf("_NET_NUMBER_OF_DESKTOPS is %d\n", desktops);
 
@@ -274,7 +280,7 @@ static void RepositionDesktop(bool updateChildren)
       
       if(data)
       {
-         current = *(long *)data;
+         current = (int)*(long *)data;
          XFree(data);
          data = null;
 
@@ -307,12 +313,14 @@ static void RepositionDesktop(bool updateChildren)
       {
          workareas = (long *)data;
      
-         x = workareas[current * 4];
-         y = workareas[current * 4 + 1];
-         w = workareas[current * 4 + 2];
-         h = workareas[current * 4 + 3];   
+         x = (int)workareas[current * 4];
+         y = (int)workareas[current * 4 + 1];
+         w = (int)workareas[current * 4 + 2];
+         h = (int)workareas[current * 4 + 3];
 
          //printf("_NET_WORKAREA is x = %d, y = %d, w = %d, h = %d\n", x, y, w, h);
+         XFree(data);
+         data = null;
       }
       //   printf("Work Area width: %d, height %d\n", w, h);
    }
@@ -407,14 +415,14 @@ static bool ProcessKeyMessage(Window window, uint keyCode, int release, XKeyEven
 */
 
    if(!buf)
-      buf = malloc(bufsize);
+      buf = malloc((uint)bufsize);
    if(windowData && windowData.ic)
    { 
-      buflength = XmbLookupString(windowData.ic, event, buf, bufsize, &keysym, &status);
+      buflength = XmbLookupString(windowData.ic, event, buf, (int)bufsize, &keysym, &status);
       if (status == XBufferOverflow)
       {
-         buf = realloc(buf, (bufsize = buflength));
-         buflength = XmbLookupString(windowData.ic, event, buf, bufsize, &keysym, &status);
+         buf = realloc(buf, (uint)(bufsize = buflength));
+         buflength = XmbLookupString(windowData.ic, event, buf, (int)bufsize, &keysym, &status);
       }
       if(status != XLookupKeySym && status != XLookupBoth && release == 1)
          keysym = XLookupKeysym(event, 0);
@@ -465,7 +473,7 @@ static bool ProcessKeyMessage(Window window, uint keyCode, int release, XKeyEven
 #ifdef __APPLE__
          case XK_Help:     key = insert; break;
 #endif
-         // case XK_Break:
+         case XK_Break:    key = Key { pauseBreak, ctrl = true }; break;
 #ifdef __APPLE__
          case XK_Mode_switch: key = leftAlt; break;
 #endif
@@ -735,11 +743,11 @@ static bool ProcessKeyMessage(Window window, uint keyCode, int release, XKeyEven
                int numBytes;
                ch = UTF8GetChar(buf + c, &numBytes);
                if(ch == 127) ch = 0;
-               if(!numBytes) c = buflength;
                result = window.KeyMessage((c == 0) ? 
                   __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown : __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit,
                   (c == 0) ? code : 0, ch);
                c += numBytes;
+               if(!numBytes) c = buflength;
             }
          }
          else
@@ -753,9 +761,9 @@ static bool ProcessKeyMessage(Window window, uint keyCode, int release, XKeyEven
                int numBytes;
                ch = UTF8GetChar(buf + c, &numBytes);
                if(ch == 127) ch = 0;
-               if(!numBytes) c = buflength;
                result = window.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit, code, ch);
                c += numBytes;
+               if(!numBytes) c = buflength;
             }
          else
             result = window.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit, code, ch);
@@ -791,9 +799,15 @@ static Bool EventChecker(void *display, XEvent *event, char * data)
 
 static Bool ConfigureNotifyChecker(void *display, XConfigureEvent *event, char * data)
 {
-   return ((!data || (event->window == (int) data)) && event->type == ConfigureNotify;
+   return ((!data || (event->window == (X11Window) data)) && event->type == ConfigureNotify;
 }
 
+static enum FrameExtentSupport { unknown, working, broken };
+
+static FrameExtentSupport frameExtentSupported;
+static Time frameExtentRequest;
+static X11Window frameExtentWindow;
+
 static uint timerDelay = MAXINT;
 #define RESOLUTION   (18.2 * 100)
 static uint XTimerThread(Thread thread)
@@ -822,6 +836,22 @@ static uint XTimerThread(Thread thread)
          if(FD_ISSET(s, &readSet))
             gotAnXEvent = true;
       }
+      if(frameExtentSupported == unknown && frameExtentRequest && GetTime() - frameExtentRequest > 1)
+      {
+         XPropertyEvent event = { 0 };
+         event.type = PropertyNotify;
+         event.state = PropertyNewValue;
+         event.atom = atoms[_net_frame_extents];
+         event.display = xGlobalDisplay;
+         event.serial = 0;
+         event.window = frameExtentWindow;
+         event.send_event = 1;
+
+         frameExtentSupported = broken;
+
+         XSendEvent(xGlobalDisplay, frameExtentWindow, bool::false,
+            PropertyChangeMask, (union _XEvent *)&event);
+      }
       xMutex.Release();
       guiApp.SignalEvent();  
       xSemaphore.Wait();
@@ -958,7 +988,7 @@ default:
 
 #include <sys/ipc.h>
 #include <sys/shm.h>
-#include <sys/signal.h>
+#include <signal.h>
 #include <locale.h>
 
 
@@ -1032,6 +1062,7 @@ class XInterface : Interface
 #endif
       xTerminate = false;
       xGlobalDisplay = XOpenDisplay(null);
+      frameExtentSupported = unknown;
 
        joystickFD[0] = open("/dev/js0", O_RDONLY);
       joystickFD[1] = open("/dev/js1", O_RDONLY);
@@ -1052,7 +1083,7 @@ class XInterface : Interface
             {
                XVisualInfo vinfo;
                XVisualInfo *vinfo_ret;
-               long numitems;
+               int numitems = 0;
               
                vinfo.visualid = XVisualIDFromVisual(xSystemVisual);
                vinfo_ret = XGetVisualInfo(xGlobalDisplay, VisualIDMask, &vinfo, &numitems);
@@ -1462,7 +1493,7 @@ class XInterface : Interface
                         event->x_root, event->y_root, &keyFlags, false, false);
                      delete window;
                      //*if(xGlobalDisplay) XLockDisplay(xGlobalDisplay);
-                     lastTime = event->time;
+                     lastTime = (uint)event->time;
                   }
                   break;
                }
@@ -1524,30 +1555,34 @@ class XInterface : Interface
                }
                case FocusIn:
                {
-                  XFocusChangeEvent *event = (XFocusChangeEvent *) thisEvent;
-                  Window modalRoot = window.FindModal();
-                  XWindowData windowData;
-                  activeWindow = (X11Window)window.windowHandle;
-
-                  if(window.parent && window == window.parent.activeChild) break;
-                  incref window;
-                  //if(window.creationActivation == activate)
-                  {
-                     if(modalRoot)
-                        modalRoot.ExternalActivate(true, true, window, null); // lastActive);
-                     else
-                        window.ExternalActivate(true, true, window, null); // lastActive); 
-                  } 
-                  windowData = modalRoot ? modalRoot.windowData : window.windowData;
-                  if(windowData && windowData.ic)
+                  if(activeWindow != (X11Window)window.windowHandle)
                   {
-                     // XSetICValues(ic, XNClientWindow, window.windowHandle, XNFocusWindow, window.windowHandle, 0);
-                     XSetICFocus(windowData.ic);
+                     XFocusChangeEvent *event = (XFocusChangeEvent *) thisEvent;
+                     Window modalRoot = window.FindModal();
+                     XWindowData windowData;
+
+                     activeWindow = (X11Window)window.windowHandle;
+
+                     if(window.parent && window == window.parent.activeChild) break;
+                     incref window;
+                     //if(window.creationActivation == activate)
+                     {
+                        if(modalRoot)
+                           modalRoot.ExternalActivate(true, true, window, null); // lastActive);
+                        else
+                           window.ExternalActivate(true, true, window, null); // lastActive);
+                     }
+                     windowData = modalRoot ? modalRoot.windowData : window.windowData;
+                     if(windowData && windowData.ic)
+                     {
+                        // XSetICValues(ic, XNClientWindow, window.windowHandle, XNFocusWindow, window.windowHandle, 0);
+                        XSetICFocus(windowData.ic);
+                     }
+                     //delete lastActive;
+                     //lastActive = window;
+                     //incref lastActive;
+                     delete window;
                   }
-                  //delete lastActive;
-                  //lastActive = window;
-                  //incref lastActive;
-                  delete window;
                   break;
                }
                case FocusOut:
@@ -1704,7 +1739,7 @@ class XInterface : Interface
                      //if(event->send_event)
                      {
                         X11Window rootChild;
-                        long rootX, rootY;
+                        int rootX, rootY;
                         XTranslateCoordinates(xGlobalDisplay, event->window,
                            RootWindow(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 0, 0, 
                            &rootX, &rootY, &rootChild);
@@ -1715,7 +1750,7 @@ class XInterface : Interface
                      x -= desktopX;
                      y -= desktopY;
 
-                     if(window.nativeDecorations)
+                     if(window.nativeDecorations && window.state != maximized)
                      {
                         x -= windowData.decor.left;
                         y -= windowData.decor.top;
@@ -1728,7 +1763,7 @@ class XInterface : Interface
                         h += window.size.h - window.clientSize.h;
                         */
                      }
-                     window.ExternalPosition(x, y, w, h);
+                     window.Position(x, y, w, h, true, true, true, true, false, false);
                   }
                   break;
                }
@@ -1748,7 +1783,7 @@ class XInterface : Interface
                      bool laterFocus;
                      activeWindow = (X11Window)window.windowHandle;
 
-                     timeStamp = event->data.l[1];
+                     timeStamp = (int)event->data.l[1];
                      
                      windowData = window.windowData;
                      laterFocus = windowData.laterFocus;
@@ -1860,27 +1895,52 @@ class XInterface : Interface
                          &fill, &data) == Success && data)
                      {
                         long *extents = (long *)data;
+                        bool change = extents[0] != windowData.decor.left ||
+                                      extents[1] != windowData.decor.right ||
+                                      extents[2] != windowData.decor.top ||
+                                      extents[3] != windowData.decor.bottom;
+
                         bool hadFrameExtents = windowData.gotFrameExtents;
-                        windowData.decor =
-                        {
-                           left = extents[0], right  = extents[1],
-                           top  = extents[2], bottom = extents[3]
-                        };
-                        windowData.gotFrameExtents = true;
+                        Box oldDecor = windowData.decor;
+
+                        frameExtentSupported = working;
+                        frameExtentWindow = 0;
+                        frameExtentRequest = 0;
+
+                        if(!hadFrameExtents || extents[0] || extents[1] || extents[2] || extents[3])
                         {
-                           int x, y, w, h;
-                           window.ComputeAnchors(
-                              window.normalAnchor,
-                              window.normalSizeAnchor,
-                              &x, &y, &w, &h);
-                           if(!hadFrameExtents) // || window.state == normal)
+                           windowData.decor =
+                           {
+                              left = (int)extents[0], right  = (int)extents[1],
+                              top  = (int)extents[2], bottom = (int)extents[3]
+                           };
+                           windowData.gotFrameExtents = true;
+                           if(change && ((Window)window).clientSize.w > 0)
                            {
-                              bool isMaximized = window.state == maximized;
-                              window.Position(x, y, w, h, true, true, true, true, false, true);
-                              UpdateRootWindow(window);
+                              int x = window.position.x, y = window.position.y, w = window.size.w, h = window.size.h;
+                              if(!hadFrameExtents && window.state != maximized)
+                              {
+                                 window.ComputeAnchors(
+                                    window.normalAnchor,
+                                    window.normalSizeAnchor,
+                                    &x, &y, &w, &h);
+                              }
+                              else
+                              {
+                                 x += windowData.decor.left - oldDecor.left;
+                                 y += windowData.decor.top - oldDecor.top;
+
+                                 w += windowData.decor.left - oldDecor.left + windowData.decor.right - oldDecor.right;
+                                 h += windowData.decor.top - oldDecor.top   + windowData.decor.bottom - oldDecor.bottom;
+                              }
+
+                              if(window.state != maximized)
+                              {
+                                 window.Position(x, y, w, h, true, true, true, true, false, !hadFrameExtents && window.state != maximized);
+                                 UpdateRootWindow(window);
+                              }
                            }
                         }
-
                         XFree(data);
                      }
                      else
@@ -1970,7 +2030,7 @@ class XInterface : Interface
       attributes.override_redirect = window.interim ? True : False;
       attributes.event_mask = EVENT_MASK;
       //printf("%s\n", guiApp.defaultDisplayDriver);
-#if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
+#if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D) && !defined(ECERE_NOGL)
       if(window.dispDriver == class(OpenGLDisplayDriver) || !strcmp(guiApp.defaultDisplayDriver, "OpenGL"))
       {
          int samples;
@@ -2119,13 +2179,18 @@ class XInterface : Interface
                0,0,1,1,0, depth, InputOutput, visual ? visual : CopyFromParent, 
                CWEventMask | CWOverrideRedirect | (visual ? (CWColormap | CWBorderPixel) : 0), &attributes);
 
-            if(parentWindow && window.interim)
+            if(parentWindow && (window.interim || window.isModal))
             {
                //printf("Setting WM_TRANSIENT_FOR of %s to %s\n", window._class.name, window.master.rootWindow._class.name);
                XSetTransientForHint(xGlobalDisplay, windowHandle, parentWindow);
                //XFlush(xGlobalDisplay);
                //printf("Done.\n");
                //XChangeProperty(xGlobalDisplay, windowHandle, atoms[wm_transient_for], XA_WINDOW, 32, PropModeReplace, (unsigned char*)&parentWindow, 1);
+               if(window.isModal)
+               {
+                  Atom hints[1] = { atoms[_net_wm_state_modal] };
+                  XChangeProperty(xGlobalDisplay, windowHandle, atoms[_net_wm_state], XA_ATOM, 32, PropModeReplace, (unsigned char*)&hints, 1);
+               }
             }
 
             {
@@ -2254,9 +2319,9 @@ class XInterface : Interface
          XUngrabPointer(xGlobalDisplay, CurrentTime);
       }
 
-      if(window.nativeDecorations)
+      if(window.nativeDecorations && frameExtentSupported != broken)
       {
-         // Maximize / Restore the window
+         // Request decoration frame extents
          XClientMessageEvent event = { 0 };
          event.type = ClientMessage;
          event.message_type = atoms[_net_request_frame_extents];
@@ -2266,9 +2331,18 @@ class XInterface : Interface
          event.send_event = 1;
          window.windowHandle = (void *)windowHandle;
          event.format = 32;
+
+         if(frameExtentSupported == unknown && !frameExtentRequest)
+         {
+            frameExtentRequest = GetTime();
+            frameExtentWindow = windowHandle;
+         }
+
          XSendEvent(xGlobalDisplay, DefaultRootWindow(xGlobalDisplay), bool::false,
             SubstructureRedirectMask | SubstructureNotifyMask, (union _XEvent *)&event);
       }
+      else
+         ((XWindowData)window.windowData).gotFrameExtents = true;
       return (void *)windowHandle;
    }
 
@@ -2314,30 +2388,41 @@ class XInterface : Interface
       //Logf("Position root window %s\n", window.name);
       if(window.windowHandle && (!window.parent || !window.parent.display))
       {
-#if defined(__APPLE__) || defined(__FreeBSD__)
          bool visible = window.visible;
-         if(window.visible)
-         {
+         if(window.visible && window.created)
             XMapWindow(xGlobalDisplay, (X11Window)window.windowHandle);
-            WaitForViewableWindow(window);
-         }
-#endif
          if(window.state == minimized) return;
 
          if(window.nativeDecorations)
          {
             XWindowData windowData = window.windowData;
-#if !defined(__APPLE__) && !defined(__FreeBSD__)
-            // TODO: How to handle frame extents not supported?
-            if(!windowData.gotFrameExtents || window.state == maximized) return;
-#endif
-            w -= window.size.w - window.clientSize.w;
-            h -= window.size.h - window.clientSize.h;
+
+            // Was commenting this out was part of #700/#795 fix, but this causes jumping of e.g. About box after getting frame extents PropertyNotify
+
+               // && window.state != maximized -- required for Cinnamon on Mint 14/15
+            if(!windowData.gotFrameExtents && window.state != maximized) return;
+
+            x -= windowData.decor.left;
+            y -= windowData.decor.top;
+
+            w -= windowData.decor.left + windowData.decor.right;
+            h -= windowData.decor.top + windowData.decor.bottom;
+
+            // Tweak for first unmaximize on Unity on Ubuntu 11.10
+            if(window.state == maximized && (desktopX + w > desktopW || desktopY + h > desktopH))
+            {
+               w -= 40;
+               h -= 40;
+            }
          }
+
+         x += desktopX;
+         y += desktopY;
+
          if(move && resize)
-            XMoveResizeWindow(xGlobalDisplay, (X11Window)window.windowHandle, x + desktopX, y + desktopY, w, h);
+            XMoveResizeWindow(xGlobalDisplay, (X11Window)window.windowHandle, x, y, w, h);
          else if(move)
-            XMoveWindow(xGlobalDisplay, (X11Window)window.windowHandle, x + desktopX, y + desktopY);
+            XMoveWindow(xGlobalDisplay, (X11Window)window.windowHandle, x, y);
          else if(resize)
             XResizeWindow(xGlobalDisplay, (X11Window)window.windowHandle, w, h);
 #if defined(__APPLE__)
@@ -2393,9 +2478,7 @@ class XInterface : Interface
          if(visible)
          {
             XMapWindow(xGlobalDisplay, (X11Window)window.windowHandle);
-#if defined(__APPLE__) || defined(__FreeBSD__)
             WaitForViewableWindow(window);
-#endif
             if(window.creationActivation == activate && state != minimized)
                ActivateRootWindow(window);
             
@@ -2443,14 +2526,28 @@ class XInterface : Interface
             {
                if(!window.nativeDecorations || (!((XWindowData)window.windowData).gotFrameExtents && window.state == maximized)) //((XWindowData)window.windowData).gotFrameExtents && (!window.nativeDecorations || window.state == state))
                {
+                  int x = window.position.x;
+                  int y = window.position.y;
+                  int w = window.size.w;
+                  int h = window.size.h;
+
+                  if(window.nativeDecorations)
+                  {
+                     XWindowData windowData = window.windowData;
+                     x -= windowData.decor.left;
+                     y -= windowData.decor.top;
+
+                     w -= windowData.decor.left + windowData.decor.right;
+                     h -= windowData.decor.top + windowData.decor.bottom;
+                  }
+                  x += desktopX;
+                  y += desktopY;
+
                   // With native decorations, we do it the first time
                   // or the WM (Gnome) is sticking it to the top/right!
                   XMoveResizeWindow(xGlobalDisplay, 
                      (X11Window)window.windowHandle,
-                     window.position.x + desktopX,
-                     window.position.y + desktopY,
-                     window.nativeDecorations ? window.clientSize.w : window.size.w,
-                     window.nativeDecorations ? window.clientSize.h : window.size.h);
+                     x, y, w, h);
                   UpdateRootWindow(window);
                }
                if(window.nativeDecorations)
@@ -2756,11 +2853,16 @@ class XInterface : Interface
                   {
                      XSelectionEvent * selection = (XSelectionEvent *) &e;
                      //printf("Got a SelectionNotify with %d (%s)\n", selection->_property, XGetAtomName(xGlobalDisplay, selection->_property));
-                     byte *data;
+                     byte *data = null;
                      unsigned long len, size = 0, dummy;
                      Atom type;
                      int format;
                      XGetWindowProperty(xGlobalDisplay, (X11Window) rootWindow.windowHandle, selection->_property ? selection->_property : atom, 0, 0, False, AnyPropertyType, &type, &format, &len, &size, &data);
+                     if(data)
+                     {
+                        XFree(data);
+                        data = null;
+                     }
                      if(size > 0)
                      {
                         if(XGetWindowProperty(xGlobalDisplay, (X11Window) rootWindow.windowHandle, selection->_property ? selection->_property : atom, 0, size, False,