| | |
| | | } |
| | | |
| | | static inline bool isFullScreen(HWND hwnd) { |
| | | Q_ASSERT(hwnd); |
| | | if (!hwnd) { |
| | | return false; |
| | | } |
| | | RECT windowRect{}; |
| | | ::GetWindowRect(hwnd, &windowRect); |
| | | // Compare to the full area of the screen, not the work area. |
| | |
| | | } |
| | | |
| | | static inline bool isWindowNoState(HWND hwnd) { |
| | | Q_ASSERT(hwnd); |
| | | if (!hwnd) { |
| | | return false; |
| | | } |
| | | #if 0 |
| | | WINDOWPLACEMENT wp{}; |
| | | wp.length = sizeof(wp); |
| | |
| | | w = (ratio - qreal(1)); |
| | | } |
| | | m = (dt - (period * w)); |
| | | //Q_ASSERT((m > qreal(0)) || qFuzzyIsNull(m)); |
| | | //Q_ASSERT(m < period); |
| | | if ((m < qreal(0)) || qFuzzyCompare(m, period) || (m > period)) { |
| | | return; |
| | | } |
| | | const qreal m_ms = (qreal(1000) * m / qreal(freq.QuadPart)); |
| | | ::Sleep(static_cast<DWORD>(std::round(m_ms))); |
| | | apis.ptimeEndPeriod(ms_granularity); |
| | | } |
| | | |
| | | static inline QPoint fromNativeLocalPosition(const QWindow *window, const QPoint &point) { |
| | | Q_ASSERT(window); |
| | | if (!window) { |
| | | return point; |
| | | } |
| | | #if 1 |
| | | return QHighDpi::fromNativeLocalPosition(point, window); |
| | | #else |
| | | return QPointF(QPointF(point) / window->devicePixelRatio()).toPoint(); |
| | | #endif |
| | | } |
| | | |
| | | static inline Win32WindowContext::WindowPart getHitWindowPart(int hitTestResult) { |
| | |
| | | QT_NATIVE_EVENT_RESULT_TYPE *result) override { |
| | | Q_UNUSED(eventType) |
| | | |
| | | auto orgLastMessageContext = lastMessageContext; |
| | | lastMessageContext = nullptr; |
| | | |
| | | // It has been observed that the pointer that Qt gives us is sometimes null on some |
| | | // machines. We need to guard against it in such scenarios. |
| | | if (!result) { |
| | |
| | | // Qt needs to refer to the WM_NCCALCSIZE message data that hasn't been processed, so we |
| | | // have to process it after Qt acquired the initial data. |
| | | auto msg = static_cast<const MSG *>(message); |
| | | if (msg->message == WM_NCCALCSIZE && orgLastMessageContext) { |
| | | if (msg->message == WM_NCCALCSIZE && lastMessageContext) { |
| | | LRESULT res; |
| | | if (Win32WindowContext::nonClientCalcSizeHandler(msg->hwnd, msg->message, |
| | | if (lastMessageContext->nonClientCalcSizeHandler(msg->hwnd, msg->message, |
| | | msg->wParam, msg->lParam, &res)) { |
| | | *result = decltype(*result)(res); |
| | | return true; |
| | |
| | | static Win32WindowContext *lastMessageContext; |
| | | |
| | | static inline void install() { |
| | | if (instance) { |
| | | return; |
| | | } |
| | | instance = new WindowsNativeEventFilter(); |
| | | installNativeEventFilter(instance); |
| | | } |
| | | |
| | | static inline void uninstall() { |
| | | if (!instance) { |
| | | return; |
| | | } |
| | | removeNativeEventFilter(instance); |
| | | delete instance; |
| | | instance = nullptr; |
| | |
| | | // forward it right away and process it in our native event filter. |
| | | if (message == WM_NCCALCSIZE) { |
| | | WindowsNativeEventFilter::lastMessageContext = ctx; |
| | | return ::CallWindowProcW(g_qtWindowProc, hWnd, message, wParam, lParam); |
| | | LRESULT result = ::CallWindowProcW(g_qtWindowProc, hWnd, message, wParam, lParam); |
| | | WindowsNativeEventFilter::lastMessageContext = nullptr; |
| | | return result; |
| | | } |
| | | |
| | | // Try hooked procedure and save result |
| | |
| | | } |
| | | |
| | | // Continue dispatching. |
| | | WindowsNativeEventFilter::lastMessageContext = ctx; |
| | | return ::CallWindowProcW(g_qtWindowProc, hWnd, message, wParam, lParam); |
| | | } |
| | | |
| | |
| | | ::SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(QWKHookedWndProc)); |
| | | |
| | | // Install global native event filter |
| | | if (!WindowsNativeEventFilter::instance) { |
| | | WindowsNativeEventFilter::install(); |
| | | } |
| | | WindowsNativeEventFilter::install(); |
| | | |
| | | // Cache window ID |
| | | windowId = winId; |
| | |
| | | POINT screenPoint{GET_X_LPARAM(dwScreenPos), GET_Y_LPARAM(dwScreenPos)}; |
| | | ::ScreenToClient(hWnd, &screenPoint); |
| | | QPoint qtScenePos = |
| | | fromNativeLocalPosition(m_windowHandle, {screenPoint.x, screenPoint.y}); |
| | | QHighDpi::fromNativeLocalPosition(QPoint{screenPoint.x, screenPoint.y}, m_windowHandle); |
| | | auto dummy = CoreWindowAgent::Unknown; |
| | | if (isInSystemButtons(qtScenePos, &dummy)) { |
| | | // We must record whether the last WM_MOUSELEAVE was filtered, because if |
| | |
| | | auto clientWidth = RECT_WIDTH(clientRect); |
| | | auto clientHeight = RECT_HEIGHT(clientRect); |
| | | |
| | | QPoint qtScenePos = fromNativeLocalPosition( |
| | | m_windowHandle, QPoint(nativeLocalPos.x, nativeLocalPos.y)); |
| | | QPoint qtScenePos = QHighDpi::fromNativeLocalPosition( |
| | | QPoint(nativeLocalPos.x, nativeLocalPos.y), m_windowHandle); |
| | | |
| | | bool isFixedSize = m_delegate->isHostSizeFixed(m_host); |
| | | bool isTitleBar = isInTitleBarDraggableArea(qtScenePos); |
| | |
| | | return true; |
| | | } |
| | | |
| | | bool Win32WindowContext::systemMenuHandler(HWND hWnd, UINT message, WPARAM wParam, |
| | | LPARAM lParam, LRESULT *result) { |
| | | return false; |
| | | } |
| | | |
| | | } |