diff options
Diffstat (limited to 'src/plugins/platforms')
| -rw-r--r-- | src/plugins/platforms/cocoa/qcocoaglcontext.mm | 21 | ||||
| -rw-r--r-- | src/plugins/platforms/cocoa/qnsview_drawing.mm | 3 | ||||
| -rw-r--r-- | src/plugins/platforms/directfb/qdirectfbconvenience.cpp | 1 | ||||
| -rw-r--r-- | src/plugins/platforms/wasm/qwasmdrag.cpp | 66 | ||||
| -rw-r--r-- | src/plugins/platforms/wasm/qwasmdrag.h | 3 | ||||
| -rw-r--r-- | src/plugins/platforms/wasm/qwasmevent.h | 1 | ||||
| -rw-r--r-- | src/plugins/platforms/wasm/qwasmwindow.cpp | 6 | ||||
| -rw-r--r-- | src/plugins/platforms/wasm/qwasmwindow.h | 1 | ||||
| -rw-r--r-- | src/plugins/platforms/wayland/qwaylandwindow.cpp | 1 | ||||
| -rw-r--r-- | src/plugins/platforms/wayland/qwaylandwindow_p.h | 1 | ||||
| -rw-r--r-- | src/plugins/platforms/windows/qwindowsscreen.cpp | 20 | ||||
| -rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.cpp | 2 | ||||
| -rw-r--r-- | src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp | 7 | ||||
| -rw-r--r-- | src/plugins/platforms/xcb/qxcbdrag.cpp | 2 | ||||
| -rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 2 |
15 files changed, 105 insertions, 32 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index adad12a4242..be05249c1b8 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -265,19 +265,26 @@ void QCocoaGLContext::updateSurfaceFormat() return value; }; - int colorSize = pixelFormatAttribute(NSOpenGLPFAColorSize); - colorSize /= 4; // The attribute includes the alpha component - m_format.setRedBufferSize(colorSize); - m_format.setGreenBufferSize(colorSize); - m_format.setBlueBufferSize(colorSize); + // Resolve color channel bits from GL, rather than NSOpenGLPFAColorSize, + // as the latter is not specific enough (combines all channels). + GLint redBits, greenBits, blueBits; + glGetIntegerv(GL_RED_BITS, &redBits); + glGetIntegerv(GL_GREEN_BITS, &greenBits); + glGetIntegerv(GL_BLUE_BITS, &blueBits); + m_format.setRedBufferSize(redBits); + m_format.setGreenBufferSize(greenBits); + m_format.setBlueBufferSize(blueBits); // Surfaces on macOS always have an alpha channel, but unless the user requested // one via setAlphaBufferSize(), which triggered setting NSOpenGLCPSurfaceOpacity // to make the surface non-opaque, we don't want to report back the actual alpha // size, as that will make the user believe the alpha channel can be used for // something useful, when in reality it can't, due to the surface being opaque. - if (m_format.alphaBufferSize() > 0) - m_format.setAlphaBufferSize(pixelFormatAttribute(NSOpenGLPFAAlphaSize)); + if (m_format.alphaBufferSize() > 0) { + GLint alphaBits; + glGetIntegerv(GL_ALPHA_BITS, &alphaBits); + m_format.setAlphaBufferSize(alphaBits); + } m_format.setDepthBufferSize(pixelFormatAttribute(NSOpenGLPFADepthSize)); m_format.setStencilBufferSize(pixelFormatAttribute(NSOpenGLPFAStencilSize)); diff --git a/src/plugins/platforms/cocoa/qnsview_drawing.mm b/src/plugins/platforms/cocoa/qnsview_drawing.mm index 64c806a087b..b3c22ff051e 100644 --- a/src/plugins/platforms/cocoa/qnsview_drawing.mm +++ b/src/plugins/platforms/cocoa/qnsview_drawing.mm @@ -183,6 +183,9 @@ { qCDebug(lcQpaDrawing) << "Backing properties changed for" << self; + if (!m_platformWindow) + return; + [self propagateBackingProperties]; // Ideally we would plumb this situation through QPA in a way that lets diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp index 881a233e694..5b86c1e1725 100644 --- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp +++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp @@ -254,6 +254,7 @@ QDirectFbKeyMap::QDirectFbKeyMap() insert(DIKS_FAVORITES , Qt::Key_Favorites); insert(DIKS_KEYBOARD , Qt::Key_Keyboard); insert(DIKS_PHONE , Qt::Key_Phone); + insert(DIKS_CALL , Qt::Key_Call) insert(DIKS_PROGRAM , Qt::Key_Guide); insert(DIKS_TIME , Qt::Key_Time); diff --git a/src/plugins/platforms/wasm/qwasmdrag.cpp b/src/plugins/platforms/wasm/qwasmdrag.cpp index 730816b9a99..6447d1e399f 100644 --- a/src/plugins/platforms/wasm/qwasmdrag.cpp +++ b/src/plugins/platforms/wasm/qwasmdrag.cpp @@ -16,6 +16,9 @@ #include <QtCore/qtimer.h> #include <QFile> +#include <private/qshapedpixmapdndwindow_p.h> +#include <private/qdnd_p.h> + #include <functional> #include <string> #include <utility> @@ -91,16 +94,13 @@ Qt::DropAction QWasmDrag::drag(QDrag *drag) return Qt::IgnoreAction; Qt::DropAction dragResult = Qt::IgnoreAction; - if (qstdweb::haveJspi()) { - QEventLoop loop; - m_dragState = std::make_unique<DragState>(drag, window, [&loop]() { loop.quit(); }); - loop.exec(); - dragResult = m_dragState->dropAction; + if (qstdweb::haveAsyncify()) { + m_dragState = std::make_unique<DragState>(drag, window, [this]() { QSimpleDrag::cancelDrag(); }); + dragResult = QSimpleDrag::drag(drag); m_dragState.reset(); - } - - if (dragResult == Qt::IgnoreAction) + } else { dragResult = QBasicDrag::drag(drag); + } return dragResult; } @@ -110,13 +110,16 @@ void QWasmDrag::onNativeDragStarted(DragEvent *event) Q_ASSERT_X(event->type == EventType::DragStart, Q_FUNC_INFO, "The event is not a DragStart event"); - event->webEvent.call<void>("preventDefault"); - // It is possible for a drag start event to arrive from another window. if (!m_dragState || m_dragState->window != event->targetWindow) { event->cancelDragStart(); return; } + setExecutedDropAction(event->dropAction); + + // We have our own window + if (shapedPixmapWindow()) + shapedPixmapWindow()->setVisible(false); m_dragState->dragImage = std::make_unique<DragState::DragImage>( m_dragState->drag->pixmap(), m_dragState->drag->mimeData(), event->targetWindow); @@ -141,8 +144,10 @@ void QWasmDrag::onNativeDragOver(DragEvent *event) event->mouseButton, event->modifiers); event->acceptDragOver(); if (dragResponse.isAccepted()) { + setExecutedDropAction(dragResponse.acceptedAction()); event->dataTransfer.setDropAction(dragResponse.acceptedAction()); } else { + setExecutedDropAction(Qt::DropAction::IgnoreAction); event->dataTransfer.setDropAction(Qt::DropAction::IgnoreAction); } } @@ -170,19 +175,22 @@ void QWasmDrag::onNativeDrop(DragEvent *event) // files, but the browser expects that accepted state is set before any // async calls. event->acceptDrop(); + setExecutedDropAction(event->dropAction); + std::shared_ptr<DragState> dragState = m_dragState; - const auto dropCallback = [&m_dragState = m_dragState, wasmWindow, targetWindowPos, + const auto dropCallback = [dragState, wasmWindow, targetWindowPos, actions, mouseButton, modifiers](QMimeData *mimeData) { - - auto dropResponse = std::make_shared<QPlatformDropQtResponse>(true, Qt::DropAction::CopyAction); - *dropResponse = QWindowSystemInterface::handleDrop(wasmWindow->window(), mimeData, + if (mimeData) { + auto dropResponse = std::make_shared<QPlatformDropQtResponse>(true, Qt::DropAction::CopyAction); + *dropResponse = QWindowSystemInterface::handleDrop(wasmWindow->window(), mimeData, targetWindowPos, actions, mouseButton, modifiers); - if (dropResponse->isAccepted()) - m_dragState->dropAction = dropResponse->acceptedAction(); + if (dragState && dropResponse->isAccepted()) + dragState->dropAction = dropResponse->acceptedAction(); - delete mimeData; + delete mimeData; + } }; event->dataTransfer.toMimeDataWithFile(dropCallback); @@ -192,13 +200,35 @@ void QWasmDrag::onNativeDragFinished(DragEvent *event) { event->webEvent.call<void>("preventDefault"); m_dragState->dropAction = event->dropAction; + setExecutedDropAction(event->dropAction); m_dragState->quitEventLoopClosure(); } +void QWasmDrag::onNativeDragEnter(DragEvent *event) +{ + event->webEvent.call<void>("preventDefault"); + + // Already dragging + if (QDragManager::self() && QDragManager::self()->object()) + return; + + // Event coming from external browser, start a drag + if (m_dragState) + m_dragState->dropAction = event->dropAction; + + setExecutedDropAction(event->dropAction); + + QDrag *drag = new QDrag(this); + drag->setMimeData(new QMimeData()); + drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction); +} + void QWasmDrag::onNativeDragLeave(DragEvent *event) { event->webEvent.call<void>("preventDefault"); - m_dragState->dropAction = event->dropAction; + if (m_dragState) + m_dragState->dropAction = event->dropAction; + setExecutedDropAction(event->dropAction); event->dataTransfer.setDropAction(Qt::DropAction::IgnoreAction); } diff --git a/src/plugins/platforms/wasm/qwasmdrag.h b/src/plugins/platforms/wasm/qwasmdrag.h index e821470c913..5bb8ec66a3c 100644 --- a/src/plugins/platforms/wasm/qwasmdrag.h +++ b/src/plugins/platforms/wasm/qwasmdrag.h @@ -32,6 +32,7 @@ public: void onNativeDrop(DragEvent *event); void onNativeDragStarted(DragEvent *event); void onNativeDragFinished(DragEvent *event); + void onNativeDragEnter(DragEvent *event); void onNativeDragLeave(DragEvent *event); // QPlatformDrag: @@ -40,7 +41,7 @@ public: private: struct DragState; - std::unique_ptr<DragState> m_dragState; + std::shared_ptr<DragState> m_dragState; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmevent.h b/src/plugins/platforms/wasm/qwasmevent.h index ef1b6129e3c..07faee3fe4b 100644 --- a/src/plugins/platforms/wasm/qwasmevent.h +++ b/src/plugins/platforms/wasm/qwasmevent.h @@ -23,6 +23,7 @@ enum class EventType { DragEnd, DragOver, DragStart, + DragEnter, DragLeave, Drop, KeyDown, diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index 264471794bd..6e8bd46ca58 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -203,6 +203,12 @@ void QWasmWindow::registerEventHandlers() QWasmDrag::instance()->onNativeDragFinished(&dragEvent); } ); + m_dragEnterCallback = QWasmEventHandler(m_window, "dragenter", + [this](emscripten::val event) { + DragEvent dragEvent(EventType::DragEnter, event, window()); + QWasmDrag::instance()->onNativeDragEnter(&dragEvent); + } + ); m_dragLeaveCallback = QWasmEventHandler(m_window, "dragleave", [this](emscripten::val event) { DragEvent dragEvent(EventType::DragLeave, event, window()); diff --git a/src/plugins/platforms/wasm/qwasmwindow.h b/src/plugins/platforms/wasm/qwasmwindow.h index 87f4d6644c7..ca5c9132ca0 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.h +++ b/src/plugins/platforms/wasm/qwasmwindow.h @@ -195,6 +195,7 @@ private: QWasmEventHandler m_dragStartCallback; QWasmEventHandler m_dragEndCallback; QWasmEventHandler m_dropCallback; + QWasmEventHandler m_dragEnterCallback; QWasmEventHandler m_dragLeaveCallback; QWasmEventHandler m_wheelEventCallback; diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index f27943070d0..2be05625971 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -513,7 +513,6 @@ void QWaylandWindow::setGeometry(const QRect &r) mWindowDecoration->update(); QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(window(), geometry()); - mSentInitialResize = true; } // Wayland has no concept of areas being exposed or not, only the entire window, when our geometry changes, we need to flag the new area as exposed diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h index 9e1bd92af30..7dda16cc776 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow_p.h +++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h @@ -334,7 +334,6 @@ protected: int mFrameCallbackTimeout = 100; QVariantMap m_properties; - bool mSentInitialResize = false; QPoint mOffset; std::optional<qreal> mScale = std::nullopt; diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index 0236669d6fb..23bbe409caa 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -450,6 +450,26 @@ QPixmap QWindowsScreen::grabWindow(WId window, int xIn, int yIn, int width, int hwnd = GetDesktopWindow(); const QRect screenGeometry = geometry(); windowSize = screenGeometry.size(); + // When dpi awareness is not set to PerMonitor, windows reports primary display or dummy + // DPI for all displays, so xIn and yIn and windowSize are calculated with a wrong DPI, + // so we need to recalculate them using the actual screen size we get from + // EnumDisplaySettings api. + const auto dpiAwareness = QWindowsContext::instance()->processDpiAwareness(); + if (dpiAwareness != QtWindows::DpiAwareness::PerMonitor && + dpiAwareness != QtWindows::DpiAwareness::PerMonitorVersion2) { + MONITORINFOEX info = {}; + info.cbSize = sizeof(MONITORINFOEX); + if (GetMonitorInfo(handle(), &info)) { + DEVMODE dm = {}; + dm.dmSize = sizeof(dm); + if (EnumDisplaySettings(info.szDevice, ENUM_CURRENT_SETTINGS, &dm)) { + qreal scale = static_cast<qreal>(dm.dmPelsWidth) / windowSize.width(); + x = static_cast<int>(static_cast<qreal>(x) * scale); + y = static_cast<int>(static_cast<qreal>(y) * scale); + windowSize = QSize(dm.dmPelsWidth, dm.dmPelsHeight); + } + } + } x += screenGeometry.x(); y += screenGeometry.y(); } diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index b77e985c965..2816982b1a8 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1732,8 +1732,10 @@ void QWindowsWindow::destroyWindow() m_surface = nullptr; } #endif + DestroyWindow(m_data.hwndTitlebar); DestroyWindow(m_data.hwnd); context->removeWindow(m_data.hwnd); + m_data.hwndTitlebar = nullptr; m_data.hwnd = nullptr; } } diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp index db3fb160593..e2f181aa628 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp @@ -82,9 +82,12 @@ void QWindowsUiaMainProvider::notifyStateChange(QAccessibleStateChangeEvent *eve { if (QAccessibleInterface *accessible = event->accessibleInterface()) { if (event->changedStates().checked || event->changedStates().checkStateMixed) { - // Notifies states changes in checkboxes and switches. + // Notifies states changes in checkboxes, switches, and checkable item view items. if (accessible->role() == QAccessible::CheckBox - || accessible->role() == QAccessible::Switch) { + || accessible->role() == QAccessible::Switch + || accessible->role() == QAccessible::Cell + || accessible->role() == QAccessible::ListItem + || accessible->role() == QAccessible::TreeItem) { if (auto provider = providerForAccessible(accessible)) { long toggleState = ToggleState_Off; if (accessible->state().checked) diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index b4c12ed1a0c..d8e41a753ef 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -856,7 +856,7 @@ void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event) if (event->data.data32[0] && event->data.data32[0] != current_target) return; - const bool dropPossible = event->data.data32[1]; + const bool dropPossible = event->data.data32[1] & 1; setCanDrop(dropPossible); if (dropPossible) { diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 2c56603fef0..7d5f0155960 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2573,7 +2573,7 @@ void QXcbWindow::setOpacity(qreal level) if (!m_window) return; - quint32 value = qRound64(qBound(qreal(0), level, qreal(1)) * 0xffffffff); + quint32 value = qRound64(qBound(qreal(0), level, qreal(1)) * qreal(0xffffffff)); xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, |
