source: tspsg/src/qtwin.cpp @ 89e5214692

appveyorimgbotreadme
Last change on this file since 89e5214692 was 89e5214692, checked in by Oleksii Serdiuk, 12 years ago

Replaced all Q_WS_xxx with Q_OS_xxx ifdefs where possible.

This is needed for compatibility with Qt 5.

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4**
5** Use, modification and distribution is allowed without limitation,
6** warranty, liability or support of any kind.
7**
8****************************************************************************/
9
10#include "qtwin.h"
11#include <QLibrary>
12#include <QApplication>
13#include <QWidget>
14#include <QList>
15#include <QPointer>
16
17#ifdef Q_WS_X11
18#include <QX11Info>
19#endif // Q_WS_X11
20
21#ifdef Q_OS_WIN32
22
23#include <qt_windows.h>
24
25// Blur behind data structures
26#define DWM_BB_ENABLE                 0x00000001  // fEnable has been specified
27#define DWM_BB_BLURREGION             0x00000002  // hRgnBlur has been specified
28#define DWM_BB_TRANSITIONONMAXIMIZED  0x00000004  // fTransitionOnMaximized has been specified
29#define WM_DWMCOMPOSITIONCHANGED        0x031E    // Composition changed window message
30
31typedef struct _DWM_BLURBEHIND
32{
33    DWORD dwFlags;
34    BOOL fEnable;
35    HRGN hRgnBlur;
36    BOOL fTransitionOnMaximized;
37} DWM_BLURBEHIND, *PDWM_BLURBEHIND;
38
39typedef struct _MARGINS
40{
41    int cxLeftWidth;
42    int cxRightWidth;
43    int cyTopHeight;
44    int cyBottomHeight;
45} MARGINS, *PMARGINS;
46
47typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL* pfEnabled);
48typedef HRESULT (WINAPI *PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS* pMarInset);
49typedef HRESULT (WINAPI *PtrDwmEnableBlurBehindWindow)(HWND hWnd, const DWM_BLURBEHIND* pBlurBehind);
50typedef HRESULT (WINAPI *PtrDwmGetColorizationColor)(DWORD *pcrColorization, BOOL *pfOpaqueBlend);
51
52static PtrDwmIsCompositionEnabled pDwmIsCompositionEnabled= 0;
53static PtrDwmEnableBlurBehindWindow pDwmEnableBlurBehindWindow = 0;
54static PtrDwmExtendFrameIntoClientArea pDwmExtendFrameIntoClientArea = 0;
55static PtrDwmGetColorizationColor pDwmGetColorizationColor = 0;
56
57
58/*
59 * Internal helper class that notifies windows if the
60 * DWM compositing state changes and updates the widget
61 * flags correspondingly.
62 */
63class WindowNotifier : public QWidget
64{
65public:
66    WindowNotifier() { winId(); }
67    void addWidget(QWidget *widget) { widgets.append(widget); }
68    void removeWidget(QWidget *widget) { widgets.removeAll(widget); }
69    bool winEvent(MSG *message, long *result);
70
71private:
72    QWidgetList widgets;
73};
74
75static bool resolveLibs()
76{
77    if (!pDwmIsCompositionEnabled) {
78        QLibrary dwmLib(QString::fromAscii("dwmapi"));
79        pDwmIsCompositionEnabled =(PtrDwmIsCompositionEnabled)dwmLib.resolve("DwmIsCompositionEnabled");
80        pDwmExtendFrameIntoClientArea = (PtrDwmExtendFrameIntoClientArea)dwmLib.resolve("DwmExtendFrameIntoClientArea");
81        pDwmEnableBlurBehindWindow = (PtrDwmEnableBlurBehindWindow)dwmLib.resolve("DwmEnableBlurBehindWindow");
82        pDwmGetColorizationColor = (PtrDwmGetColorizationColor)dwmLib.resolve("DwmGetColorizationColor");
83    }
84    return pDwmIsCompositionEnabled != 0;
85}
86
87#endif
88
89/*!
90  * Chekcs and returns true if Windows DWM composition
91  * is currently enabled on the system.
92  *
93  * To get live notification on the availability of
94  * this feature, you will currently have to
95  * reimplement winEvent() on your widget and listen
96  * for the WM_DWMCOMPOSITIONCHANGED event to occur.
97  *
98  */
99bool QtWin::isCompositionEnabled()
100{
101#ifdef Q_OS_WIN32
102    if (resolveLibs()) {
103        HRESULT hr = S_OK;
104        BOOL isEnabled = false;
105        hr = pDwmIsCompositionEnabled(&isEnabled);
106        if (SUCCEEDED(hr))
107            return isEnabled;
108    }
109    return false;
110#elif defined(Q_WS_X11)
111    return QX11Info::isCompositingManagerRunning();
112#else
113    //! \todo TODO: Check for trsnsparency support in other OSes.
114    return false;
115#endif
116}
117
118/*!
119  * Enables Blur behind on a Widget.
120  *
121  * \a enable tells if the blur should be enabled or not
122  */
123bool QtWin::enableBlurBehindWindow(QWidget *widget, bool enable)
124{
125    Q_ASSERT(widget);
126    bool result = false;
127#ifdef Q_OS_WIN32
128    if (resolveLibs()) {
129        DWM_BLURBEHIND bb = {0};
130        HRESULT hr = S_OK;
131        bb.fEnable = enable;
132        bb.dwFlags = DWM_BB_ENABLE;
133        bb.hRgnBlur = NULL;
134#endif
135        widget->setAttribute(Qt::WA_TranslucentBackground, enable);
136        widget->setAttribute(Qt::WA_NoSystemBackground, enable);
137#ifdef Q_OS_WIN32
138        hr = pDwmEnableBlurBehindWindow(HWND(widget->winId()), &bb);
139        if (SUCCEEDED(hr)) {
140            result = true;
141            windowNotifier()->addWidget(widget);
142        }
143    }
144#endif
145    return result;
146}
147
148/*!
149  * ExtendFrameIntoClientArea.
150  *
151  * This controls the rendering of the frame inside the window.
152  * Note that passing margins of -1 (the default value) will completely
153  * remove the frame from the window.
154  *
155  * \note you should not call enableBlurBehindWindow before calling
156  *       this functions
157  *
158  * \a enable tells if the blur should be enabled or not
159  */
160bool QtWin::extendFrameIntoClientArea(QWidget *widget, int left, int top, int right, int bottom)
161{
162
163    Q_ASSERT(widget);
164    Q_UNUSED(widget);
165    Q_UNUSED(left);
166    Q_UNUSED(top);
167    Q_UNUSED(right);
168    Q_UNUSED(bottom);
169
170    bool result = false;
171#ifdef Q_OS_WIN32
172    if (resolveLibs()) {
173        QLibrary dwmLib(QString::fromAscii("dwmapi"));
174        HRESULT hr = S_OK;
175        MARGINS m = {left, top, right, bottom};
176        hr = pDwmExtendFrameIntoClientArea(HWND(widget->winId()), &m);
177        if (SUCCEEDED(hr)) {
178            result = true;
179            windowNotifier()->addWidget(widget);
180        }
181        widget->setAttribute(Qt::WA_TranslucentBackground, result);
182    }
183#endif
184    return result;
185}
186
187/*!
188  * Returns the current colorizationColor for the window.
189  *
190  * \a enable tells if the blur should be enabled or not
191  */
192QColor QtWin::colorizatinColor()
193{
194    QColor resultColor = QApplication::palette().window().color();
195
196#ifdef Q_OS_WIN32
197    if (resolveLibs()) {
198        DWORD color = 0;
199        BOOL opaque = FALSE;
200        QLibrary dwmLib(QString::fromAscii("dwmapi"));
201        HRESULT hr = S_OK;
202        hr = pDwmGetColorizationColor(&color, &opaque);
203        if (SUCCEEDED(hr))
204            resultColor = QColor(color);
205    }
206#endif
207    return resultColor;
208}
209
210#ifdef Q_OS_WIN32
211WindowNotifier *QtWin::windowNotifier()
212{
213    static WindowNotifier *windowNotifierInstance = 0;
214    if (!windowNotifierInstance)
215        windowNotifierInstance = new WindowNotifier;
216    return windowNotifierInstance;
217}
218
219
220/* Notify all enabled windows that the DWM state changed */
221bool WindowNotifier::winEvent(MSG *message, long *result)
222{
223    if (message && message->message == WM_DWMCOMPOSITIONCHANGED) {
224        bool compositionEnabled = QtWin::isCompositionEnabled();
225        foreach(QWidget * widget, widgets) {
226            if (widget) {
227                widget->setAttribute(Qt::WA_NoSystemBackground, compositionEnabled);
228            }
229            widget->update();
230        }
231    }
232    return QWidget::winEvent(message, result);
233}
234#endif
Note: See TracBrowser for help on using the repository browser.