[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