[vlc-commits] [Git][videolan/vlc][master] 3 commits: qt, windows: fix updating client area with CSD

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sun Apr 23 11:51:24 UTC 2023



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
c754412e by Prince Gupta at 2023-04-23T11:34:07+00:00
qt, windows: fix updating client area with CSD

- - - - -
cdb94e5e by Prince Gupta at 2023-04-23T11:34:07+00:00
qt: fix CSD with win7 compositor

don't remove WS_CAPTION style from main window
and correctly handle client area messages

fixes #27692
fixes #27691

- - - - -
82e52751 by Prince Gupta at 2023-04-23T11:34:07+00:00
qt, windows: correctly handle capture mouse for CSD

- - - - -


1 changed file:

- modules/gui/qt/maininterface/mainctx_win32.cpp


Changes:

=====================================
modules/gui/qt/maininterface/mainctx_win32.cpp
=====================================
@@ -215,12 +215,11 @@ private:
 class CSDWin32EventHandler : public QObject, public QAbstractNativeEventFilter
 {
 public:
-    CSDWin32EventHandler(const bool useClientSideDecoration, const bool isWin7Compositor, QWindow *window, CSDButtonModel *buttonmodel, QObject *parent)
+    CSDWin32EventHandler(const bool useClientSideDecoration, QWindow *window, CSDButtonModel *buttonmodel, QObject *parent)
         : QObject {parent}
         , m_useClientSideDecoration {useClientSideDecoration}
         , m_window {window}
         , m_buttonmodel {buttonmodel}
-        , m_isWin7Compositor {isWin7Compositor}
     {
         QApplication::instance()->installNativeEventFilter(this);
         updateCSDSettings();
@@ -253,6 +252,13 @@ public:
 
         switch ( msg->message )
         {
+        case WM_SHOWWINDOW:
+        {
+            // on window show, update client frame in case DWM settings were updated
+            if (msg->wParam) updateClientFrame();
+            return false;
+        }
+
         case WM_NCCALCSIZE:
         {
             /* This is used to remove the decoration instead of using FramelessWindowHint because
@@ -385,6 +391,30 @@ public:
             break;
         }
 
+        case WM_NCLBUTTONDOWN:
+        {
+
+            // manually trigger button here, UI will never get click
+            // signal because we have captured the mouse in non client area
+            switch ( msg->wParam )
+            {
+            case HTCLOSE:
+                trigger(CSDButton::Close);
+                break;
+            case HTMINBUTTON:
+                trigger(CSDButton::Minimize);
+                break;
+            case HTMAXBUTTON:
+                trigger(CSDButton::MaximizeRestore);
+                break;
+            }
+
+
+            // required for win7 compositor, otherwise this
+            // paints default min/max/close buttons
+            return true;
+        }
+
         case WM_NCMOUSELEAVE:
         case WM_MOUSELEAVE:
         {
@@ -408,34 +438,35 @@ public:
     }
 
 private:
+    void updateClientFrame()
+    {
+        auto hwnd = (HWND)m_window->winId();
+
+        MARGINS margin {};
+
+        // set top client area to 1 pixel tall in case of user decorations
+        // with winapi magic, this add rounded corners and shadows to the window
+        //
+        // warning1: if you set margin.cyTopHeight to 1
+        // that somehow breaks snaplayouts menu with WS_CAPTION style ^_____^
+        //
+        // warning2: if you set negative margin, the window will start painting
+        // default CSD button underneath the qml layer, you won't be able to see
+        // it but those will capture all your CSD events.
+        margin.cxLeftWidth = (m_useClientSideDecoration ? 1 : 0);
+
+        DwmExtendFrameIntoClientArea(hwnd, &margin);
+    }
+
     void updateCSDSettings()
     {
         HWND winId = WinId(m_window);
         if ( !winId )
             return;
 
-        if (m_isWin7Compositor)
-        {
-            // special case for win7 compositor
-            // removing CSD borders with win7 compositor works with Qt::FramelessWindowHint
-            // but with that the shadows don't work, so manually remove WS_CAPTION style
-            DWORD style = m_nonCSDGwlStyle == 0 ? GetWindowLong(winId, GWL_STYLE) : m_nonCSDGwlStyle;
-            if (m_nonCSDGwlStyle == 0)
-                m_nonCSDGwlStyle = style;
-            if (m_useClientSideDecoration)
-            {
-                style &= ~WS_CAPTION;
-                style |= (WS_MAXIMIZEBOX | WS_THICKFRAME);
-            }
-            SetWindowLong (winId, GWL_STYLE, style);
-        }
-
-        // add back shadows
-        // with positive margins, snap layouts menu (windows 11) won't appear
-        const int margin = (m_useClientSideDecoration ? - 1 : 0);
-        const MARGINS m {margin, margin, margin, margin};
-        DwmExtendFrameIntoClientArea(winId, &m);
+        updateClientFrame();
 
+        // trigger window update, this applies changes done in updateClientFrame
         SetWindowPos(winId, NULL, 0, 0, 0, 0,
             SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS |
             SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION |
@@ -464,6 +495,18 @@ private:
         vlc_assert_unreachable();
     }
 
+    void trigger(CSDButton::ButtonType type)
+    {
+        for (auto button : m_buttonmodel->windowCSDButtons()) {
+            if (button->type() == type) {
+                button->click();
+                return ;
+            }
+        }
+
+        vlc_assert_unreachable();
+    }
+
     void setAllUnhovered()
     {
         for (auto button : m_buttonmodel->windowCSDButtons())
@@ -472,12 +515,10 @@ private:
         }
     }
 
-    DWORD m_nonCSDGwlStyle = 0;
     bool m_useClientSideDecoration;
     QWindow *m_window;
     CSDButtonModel *m_buttonmodel;
     bool m_trackingMouse = false;
-    const bool m_isWin7Compositor;
 };
 
 }
@@ -747,7 +788,6 @@ InterfaceWindowHandlerWin32::InterfaceWindowHandlerWin32(qt_intf_t *_p_intf, Mai
 
 #if QT_CLIENT_SIDE_DECORATION_AVAILABLE
     , m_CSDWindowEventHandler(new CSDWin32EventHandler(mainCtx->useClientSideDecoration(),
-                                                       _p_intf->p_compositor->type() == vlc::Compositor::Win7Compositor,
                                                        window, mainCtx->csdButtonModel(), window))
 #endif
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/ff920de8e5ca56e41b72dd00fa606fe4c376aca7...82e5275184fcea06e2fe7f7c173acc3f1799680e

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/ff920de8e5ca56e41b72dd00fa606fe4c376aca7...82e5275184fcea06e2fe7f7c173acc3f1799680e
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list