ecere/gui/drivers/XInterface: Fixed SetMouseRange confinement offset by desktopX/Y
[sdk] / ecere / src / gui / drivers / XInterface.ec
index bdc9585..e7e9135 100644 (file)
@@ -1045,7 +1045,9 @@ static bool RequestFrameExtents(Window window)
 
       XSendEvent(xGlobalDisplay, DefaultRootWindow(xGlobalDisplay), bool::false,
          SubstructureRedirectMask | SubstructureNotifyMask, (union _XEvent *)&event);
+      return true;
    }
+   return false;
 }
 
 static bool GetFrameExtents(Window window, bool update)
@@ -1191,7 +1193,7 @@ static void SigIntHandler(int value)
    }
    /*
    struct shmid_ds info;
-       int maxid = shmctl (0, SHM_INFO, &info);
+   int maxid = shmctl (0, SHM_INFO, &info);
    int pid = getpgrp();
    int thisPid = getpid();
    //if(thisPid == pid)
@@ -1200,11 +1202,11 @@ static void SigIntHandler(int value)
       if(maxid >= 0)
       {
          int id;
-             for(id = 0; id <= maxid; id++)
+         for(id = 0; id <= maxid; id++)
          {
-                struct shmid_ds shmseg;
+            struct shmid_ds shmseg;
             int shmid;
-                     if((shmid = shmctl(id, SHM_STAT, &shmseg)) >= 0)
+            if((shmid = shmctl(id, SHM_STAT, &shmseg)) >= 0)
             {
                if(shmseg.shm_cpid == pid || shmseg.shm_cpid == thisPid)
                {
@@ -1241,7 +1243,7 @@ class XInterface : Interface
       xGlobalDisplay = XOpenDisplay(null);
       frameExtentSupported = unknown;
 
-       joystickFD[0] = open("/dev/js0", O_RDONLY);
+      joystickFD[0] = open("/dev/js0", O_RDONLY);
       joystickFD[1] = open("/dev/js1", O_RDONLY);
       joystickFD[2] = open("/dev/js2", O_RDONLY);
       joystickFD[3] = open("/dev/js3", O_RDONLY);
@@ -1532,10 +1534,33 @@ class XInterface : Interface
                case KeyPress:
                {
                   XKeyEvent * event = (XKeyEvent *) thisEvent;
+                  incref window;
+                  if(!window.active)
+                  {
+                     Window modalRoot = window.FindModal();
+                     XWindowData windowData;
+
+                     activeWindow = (X11Window)window.windowHandle;
+
+                     if(!window.parent || window != window.parent.activeChild)
+                     {
+                        if(modalRoot)
+                           modalRoot.ExternalActivate(true, true, window, null);
+                        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);
+                        }
+                     }
+                  }
                   //*XUnlockDisplay(xGlobalDisplay);
                   ProcessKeyMessage(window, event->keycode, (event->keycode == lastKeyCode) ? 2 : 0, event);
                   //*if(xGlobalDisplay) XLockDisplay(xGlobalDisplay);
                   lastKeyCode = event->keycode;
+                  delete window;
                   break;
                }
                case KeyRelease:
@@ -1745,9 +1770,9 @@ class XInterface : Interface
                }
                case SelectionRequest:
                {
-                   XSelectionRequestEvent *req = (XSelectionRequestEvent *) thisEvent;
-                   XEvent respond;
-                        if(req->target == atoms[targets] && clipBoardData)
+                  XSelectionRequestEvent *req = (XSelectionRequestEvent *) thisEvent;
+                  XEvent respond;
+                  if(req->target == atoms[targets] && clipBoardData)
                   {
                      Atom * supportedTargets = new Atom[4];
                      supportedTargets[0] = atoms[targets];
@@ -1755,27 +1780,27 @@ class XInterface : Interface
                      supportedTargets[2] = XA_STRING;
                      supportedTargets[3] = atoms[utf8_string];
                      XChangeProperty(xGlobalDisplay,req->requestor, req->_property,
-                                        XA_ATOM,32,PropModeReplace, (byte *) supportedTargets, 4*sizeof(Atom));
+                        XA_ATOM,32,PropModeReplace, (byte *) supportedTargets, 4*sizeof(Atom));
                      respond.xselection._property = req->_property;
                      delete supportedTargets;
                   }
                   else if((req->target == XA_STRING || req->target == atoms[utf8_string]) && clipBoardData)
-                        {
+                  {
                      Atom _property = (req->_property == None) ? req->target : req->_property;
-                                XChangeProperty(xGlobalDisplay,req->requestor, _property,
-                                        req->target/*req->_property*/,8,PropModeReplace, (byte *) clipBoardData, strlen(clipBoardData));
-                                respond.xselection._property = _property;
-                        }
+                     XChangeProperty(xGlobalDisplay,req->requestor, _property,
+                        req->target/*req->_property*/,8,PropModeReplace, (byte *) clipBoardData, strlen(clipBoardData));
+                     respond.xselection._property = _property;
+                  }
                   else
-                                respond.xselection._property = None;
+                     respond.xselection._property = None;
 
                   respond.xselection.type = SelectionNotify;
-                        respond.xselection.display = req->display;
-                        respond.xselection.requestor = req->requestor;
-                        respond.xselection.selection =req->selection;
-                        respond.xselection.target = req->target;
-                        respond.xselection.time = CurrentTime;
-                        XSendEvent(xGlobalDisplay, req->requestor,0,0,&respond);
+                  respond.xselection.display = req->display;
+                  respond.xselection.requestor = req->requestor;
+                  respond.xselection.selection =req->selection;
+                  respond.xselection.target = req->target;
+                  respond.xselection.time = CurrentTime;
+                  XSendEvent(xGlobalDisplay, req->requestor,0,0,&respond);
                   break;
                }
                case SelectionClear:
@@ -1976,13 +2001,14 @@ class XInterface : Interface
                      }
                   }
                   {
+                     bool offset = false;
                      int x, y, w, h;
                      if(unmaximized)
                      {
-                        // Ensure we set the normal size anchor when un-maximizing
                         if(window.nativeDecorations && RequestFrameExtents(window))
                            WaitForFrameExtents(window);
-                        x = window.position.x, y = window.position.y, w = window.size.w, h = window.size.h;
+
+                        // Ensure we set the normal size anchor when un-maximizing
                         window.ComputeAnchors(window.normalAnchor, window.normalSizeAnchor, &x, &y, &w, &h);
                      }
                      else
@@ -1998,8 +2024,12 @@ class XInterface : Interface
                            XTranslateCoordinates(xGlobalDisplay, event->window,
                               RootWindow(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 0, 0,
                               &rootX, &rootY, &rootChild);
-                           x = rootX;
-                           y = rootY;
+                           if(x != rootX || y != rootY)
+                           {
+                              x = rootX;
+                              y = rootY;
+                              offset = true;
+                           }
                         }
 
                         x -= desktopX;
@@ -2011,6 +2041,7 @@ class XInterface : Interface
                            y -= windowData.decor.top;
                            w += windowData.decor.left + windowData.decor.right;
                            h += windowData.decor.top + windowData.decor.bottom;
+
                            /*
                            x -= window.clientStart.x;
                            y -= window.clientStart.y - (window.hasMenuBar ? skinMenuHeight : 0);
@@ -2020,23 +2051,20 @@ class XInterface : Interface
                         }
                      }
 
-                     // Break the anchors for moveable/resizable windows
-                     if(window.style.fixed && window.state == normal)
-                     {
-                        window.normalAnchor = Anchor { left = x, top = y };
-                        window.normalSizeAnchor = SizeAnchor { { w, h } };
-                        window.anchored = false;
-                     }
+                     window.Position(x, y, w, h, true, true, true, true, false, unmaximized);
 
                      // Break the anchors for moveable/resizable windows
-                     if(window.style.fixed && window.state == normal)
+                     // Avoid doing this if the translation wasn't in sync as it will cause the window to move around
+                     if(!unmaximized && !offset && window.style.fixed && window.state == normal)
                      {
-                        window.normalAnchor = Anchor { left = x, top = y };
-                        window.normalSizeAnchor = SizeAnchor { { w, h } };
-                        window.anchored = false;
+                        window.normalAnchor = Anchor
+                        {
+                           left = x + windowData.decor.left,
+                           top = y + windowData.decor.top
+                        };
+                        window.normalSizeAnchor =
+                           SizeAnchor { { window.clientSize.w, window.clientSize.h }, isClientW = true, isClientH = true };
                      }
-
-                     window.Position(x, y, w, h, true, true, true, true, false, unmaximized);
                   }
                   break;
                }
@@ -2382,6 +2410,18 @@ class XInterface : Interface
             int x = window.position.x + desktopX, y = window.position.y + desktopY;
             int w = window.state == normal ? Max(1, window.size.w) : Max(1, window.normalSizeAnchor.size.w);
             int h = window.state == normal ? Max(1, window.size.h) : Max(1, window.normalSizeAnchor.size.h);
+            MinMaxValue smw = 0, smh = 0;
+            MinMaxValue minW = window.minSize.w, minH = window.minSize.h;
+            window.OnResizing((int *)&minW, (int *)&minH);
+
+            // To fix jumping message boxes on Cinnamon:
+            if(window.state == normal && (minW > window.minSize.w || minH > window.minSize.w))
+               window.ComputeAnchors(window.normalAnchor, window.normalSizeAnchor, &x, &y, &w, &h);
+
+            window.SetWindowMinimum(&smw, &smh);
+            minW = Max(minW, smw);
+            minH = Max(minH, smh);
+
             if(!window.nativeDecorations && window.state != normal)
             {
                w += window.size.w - window.clientSize.w;
@@ -2441,17 +2481,13 @@ class XInterface : Interface
                }
 
                // Set Normal hints for minimum/maximum size
-               if(true) //window.minSize.w || window.minSize.h || window.maxSize.w < MAXINT || window.maxSize.h < MAXINT)
+               if(true)
                {
                   XSizeHints hints = { 0 };
-                  MinMaxValue mw, mh;
-                  window.SetWindowMinimum(&mw, &mh);
-                  if(window.minSize.w || window.minSize.h)
-                  {
-                     hints.min_width = Max(window.minSize.w, mw);
-                     hints.min_height = Max(window.minSize.h, mh);
-                     hints.flags |= PMinSize;
-                  }
+                  hints.min_width = minW;
+                  hints.min_height = minH;
+                  hints.flags |= PMinSize;
+
                   if(window.maxSize.w < MAXINT || window.minSize.h < MAXINT)
                   {
                      hints.max_width = window.maxSize.w;
@@ -2508,8 +2544,8 @@ class XInterface : Interface
       }
       if(ic)
       {
-             XGetICValues(ic, XNFilterEvents, &mask, NULL);
-             mask |= EVENT_MASK;
+         XGetICValues(ic, XNFilterEvents, &mask, NULL);
+         mask |= EVENT_MASK;
       }
       /*
       XSelectInput(xGlobalDisplay, windowHandle, mask);
@@ -2669,6 +2705,16 @@ class XInterface : Interface
                XMoveWindow(xGlobalDisplay, (X11Window)window.windowHandle, x, y);
             else if(resize)
                XResizeWindow(xGlobalDisplay, (X11Window)window.windowHandle, w, h);
+
+            // Reset min/max for fixed size windows on WMs not looking at MWM_FUNC_RESIZE (e.g. Cinnamon)
+            if(window.style.fixed && !window.style.sizable)
+            {
+               XSizeHints hints = { 0 };
+               hints.min_width = hints.max_width = w;
+               hints.min_height = hints.max_height = h;
+               hints.flags |= PMinSize|PMaxSize|PPosition|PSize;
+               XSetWMNormalHints(xGlobalDisplay, (X11Window)window.windowHandle, &hints);
+            }
          }
 #if defined(__APPLE__)
 //         if(window.created && !visible)
@@ -2897,7 +2943,7 @@ class XInterface : Interface
       {
          if(!window.parent || !window.parent.display)
          {
-            XMoveResizeWindow(xGlobalDisplay, confineWindow, box.left + desktopX, box.top + desktopY,
+            XMoveResizeWindow(xGlobalDisplay, confineWindow, box.left /*+ desktopX*/, box.top /*+ desktopY*/,
                box.right - box.left + 1, box.bottom - box.top + 1);
 
             if(!restrictedWindow)
@@ -2961,8 +3007,9 @@ class XInterface : Interface
 
    void SetMouseCursor(Window window, int cursor)
    {
-      XDefineCursor(xGlobalDisplay, (X11Window) window.rootWindow.windowHandle,
-         cursor == -1 ? (X11Cursor)0 : systemCursors[(SystemCursor)cursor]);
+      if(window.rootWindow.windowHandle)
+         XDefineCursor(xGlobalDisplay, (X11Window) window.rootWindow.windowHandle,
+            cursor == -1 ? (X11Cursor)0 : systemCursors[(SystemCursor)cursor]);
    }
 
    // --- Caret ---
@@ -2993,7 +3040,7 @@ class XInterface : Interface
       if(clipBoardData)
       {
          delete clipBoardData;
-       XSetSelectionOwner(xGlobalDisplay, atoms[clipboard], None, CurrentTime);
+         XSetSelectionOwner(xGlobalDisplay, atoms[clipboard], None, CurrentTime);
       }
       //*XUnlockDisplay(xGlobalDisplay);
    }
@@ -3181,8 +3228,8 @@ class XInterface : Interface
             else
                memcpy(icon + 2, bitmap.picture, bitmap.width * bitmap.height * sizeof(uint32));
             XChangeProperty(xGlobalDisplay, (X11Window)window.windowHandle, atoms[_net_wm_icon],
-                         XA_CARDINAL,32,PropModeReplace, (byte *)icon, 2+bitmap.width*bitmap.height);
-           delete icon;
+              XA_CARDINAL,32,PropModeReplace, (byte *)icon, 2+bitmap.width*bitmap.height);
+            delete icon;
          }
          delete bitmap;
       }