Refactor all ui_platform_utility functions to accept QWidget

Also let ShowWindowMenu accept the point and remove unused return data
This commit is contained in:
Ilya Fedin 2022-05-24 10:12:24 +04:00 committed by John Preston
parent de5aa43f15
commit a714fb0070
11 changed files with 77 additions and 74 deletions

View file

@ -158,7 +158,7 @@ bool WaylandIntegration::windowExtentsSupported() {
} }
void WaylandIntegration::setWindowExtents( void WaylandIntegration::setWindowExtents(
QWindow *window, not_null<QWidget*> widget,
const QMargins &extents) { const QMargins &extents) {
const auto native = QGuiApplication::platformNativeInterface(); const auto native = QGuiApplication::platformNativeInterface();
if (!native) { if (!native) {
@ -166,38 +166,42 @@ void WaylandIntegration::setWindowExtents(
} }
native->setWindowProperty( native->setWindowProperty(
window->handle(), widget->windowHandle()->handle(),
"_desktopApp_waylandCustomMargins", "_desktopApp_waylandCustomMargins",
QVariant::fromValue<QMargins>(extents)); QVariant::fromValue<QMargins>(extents));
} }
void WaylandIntegration::unsetWindowExtents(QWindow *window) { void WaylandIntegration::unsetWindowExtents(not_null<QWidget*> widget) {
const auto native = QGuiApplication::platformNativeInterface(); const auto native = QGuiApplication::platformNativeInterface();
if (!native) { if (!native) {
return; return;
} }
native->setWindowProperty( native->setWindowProperty(
window->handle(), widget->windowHandle()->handle(),
"_desktopApp_waylandCustomMargins", "_desktopApp_waylandCustomMargins",
QVariant()); QVariant());
} }
bool WaylandIntegration::showWindowMenu(QWindow *window) { void WaylandIntegration::showWindowMenu(
not_null<QWidget*> widget,
const QPoint &point) {
const auto native = QGuiApplication::platformNativeInterface(); const auto native = QGuiApplication::platformNativeInterface();
if (!native) { if (!native) {
return false; return;
} }
const auto toplevel = reinterpret_cast<xdg_toplevel*>( const auto toplevel = reinterpret_cast<xdg_toplevel*>(
native->nativeResourceForWindow(QByteArray("xdg_toplevel"), window)); native->nativeResourceForWindow(
QByteArray("xdg_toplevel"),
widget->windowHandle()));
const auto seat = reinterpret_cast<wl_seat*>( const auto seat = reinterpret_cast<wl_seat*>(
native->nativeResourceForIntegration(QByteArray("wl_seat"))); native->nativeResourceForIntegration(QByteArray("wl_seat")));
const auto serial = [&]() -> std::optional<uint32_t> { const auto serial = [&]() -> std::optional<uint32_t> {
const auto waylandWindow = static_cast<QWaylandWindow*>( const auto waylandWindow = static_cast<QWaylandWindow*>(
window->handle()); widget->windowHandle()->handle());
if (!waylandWindow) { if (!waylandWindow) {
return std::nullopt; return std::nullopt;
} }
@ -205,14 +209,10 @@ bool WaylandIntegration::showWindowMenu(QWindow *window) {
}(); }();
if (!toplevel || !seat || !serial) { if (!toplevel || !seat || !serial) {
return false; return;
} }
const auto pos = window->mapFromGlobal(QCursor::pos()) xdg_toplevel_show_window_menu(toplevel, seat, *serial, point.x(), point.y());
* window->devicePixelRatio();
xdg_toplevel_show_window_menu(toplevel, seat, *serial, pos.x(), pos.y());
return true;
} }
} // namespace Platform } // namespace Platform

View file

@ -19,9 +19,9 @@ public:
void waitForInterfaceAnnounce(); void waitForInterfaceAnnounce();
[[nodiscard]] bool xdgDecorationSupported(); [[nodiscard]] bool xdgDecorationSupported();
[[nodiscard]] bool windowExtentsSupported(); [[nodiscard]] bool windowExtentsSupported();
void setWindowExtents(QWindow *window, const QMargins &extents); void setWindowExtents(not_null<QWidget*> widget, const QMargins &extents);
void unsetWindowExtents(QWindow *window); void unsetWindowExtents(not_null<QWidget*> widget);
bool showWindowMenu(QWindow *window); void showWindowMenu(not_null<QWidget*> widget, const QPoint &point);
private: private:
WaylandIntegration(); WaylandIntegration();

View file

@ -38,15 +38,16 @@ bool WaylandIntegration::windowExtentsSupported() {
} }
void WaylandIntegration::setWindowExtents( void WaylandIntegration::setWindowExtents(
QWindow *window, not_null<QWidget*> widget,
const QMargins &extents) { const QMargins &extents) {
} }
void WaylandIntegration::unsetWindowExtents(QWindow *window) { void WaylandIntegration::unsetWindowExtents(not_null<QWidget*> widget) {
} }
bool WaylandIntegration::showWindowMenu(QWindow *window) { void WaylandIntegration::showWindowMenu(
return false; not_null<QWidget*> widget,
const QPoint &point) {
} }
} // namespace Platform } // namespace Platform

View file

@ -21,7 +21,6 @@
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION #endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
#include <QtCore/QPoint> #include <QtCore/QPoint>
#include <QtGui/QWindow>
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
namespace Ui { namespace Ui {
@ -291,7 +290,7 @@ std::optional<bool> XCBIsOverlapped(
return false; return false;
} }
void SetXCBFrameExtents(QWindow *window, const QMargins &extents) { void SetXCBFrameExtents(not_null<QWidget*> widget, const QMargins &extents) {
const auto connection = base::Platform::XCB::GetConnectionFromQt(); const auto connection = base::Platform::XCB::GetConnectionFromQt();
if (!connection) { if (!connection) {
return; return;
@ -305,17 +304,18 @@ void SetXCBFrameExtents(QWindow *window, const QMargins &extents) {
return; return;
} }
const auto nativeExtents = extents * widget->devicePixelRatioF();
const auto extentsVector = std::vector<uint>{ const auto extentsVector = std::vector<uint>{
uint(extents.left()), uint(nativeExtents.left()),
uint(extents.right()), uint(nativeExtents.right()),
uint(extents.top()), uint(nativeExtents.top()),
uint(extents.bottom()), uint(nativeExtents.bottom()),
}; };
xcb_change_property( xcb_change_property(
connection, connection,
XCB_PROP_MODE_REPLACE, XCB_PROP_MODE_REPLACE,
window->winId(), widget->winId(),
*frameExtentsAtom, *frameExtentsAtom,
XCB_ATOM_CARDINAL, XCB_ATOM_CARDINAL,
32, 32,
@ -323,7 +323,7 @@ void SetXCBFrameExtents(QWindow *window, const QMargins &extents) {
extentsVector.data()); extentsVector.data());
} }
void UnsetXCBFrameExtents(QWindow *window) { void UnsetXCBFrameExtents(not_null<QWidget*> widget) {
const auto connection = base::Platform::XCB::GetConnectionFromQt(); const auto connection = base::Platform::XCB::GetConnectionFromQt();
if (!connection) { if (!connection) {
return; return;
@ -339,19 +339,19 @@ void UnsetXCBFrameExtents(QWindow *window) {
xcb_delete_property( xcb_delete_property(
connection, connection,
window->winId(), widget->winId(),
*frameExtentsAtom); *frameExtentsAtom);
} }
bool ShowXCBWindowMenu(QWindow *window) { void ShowXCBWindowMenu(not_null<QWidget*> widget, const QPoint &point) {
const auto connection = base::Platform::XCB::GetConnectionFromQt(); const auto connection = base::Platform::XCB::GetConnectionFromQt();
if (!connection) { if (!connection) {
return false; return;
} }
const auto root = base::Platform::XCB::GetRootWindow(connection); const auto root = base::Platform::XCB::GetRootWindow(connection);
if (!root.has_value()) { if (!root.has_value()) {
return false; return;
} }
const auto showWindowMenuAtom = base::Platform::XCB::GetAtom( const auto showWindowMenuAtom = base::Platform::XCB::GetAtom(
@ -359,16 +359,23 @@ bool ShowXCBWindowMenu(QWindow *window) {
"_GTK_SHOW_WINDOW_MENU"); "_GTK_SHOW_WINDOW_MENU");
if (!showWindowMenuAtom.has_value()) { if (!showWindowMenuAtom.has_value()) {
return false; return;
} }
const auto globalPos = QCursor::pos(); const auto windowGeometry = XCBWindowGeometry(widget->winId());
if (windowGeometry.isNull()) {
return;
}
const auto globalPos = point
* widget->devicePixelRatioF()
+ windowGeometry.topLeft();
xcb_client_message_event_t xev; xcb_client_message_event_t xev;
xev.response_type = XCB_CLIENT_MESSAGE; xev.response_type = XCB_CLIENT_MESSAGE;
xev.type = *showWindowMenuAtom; xev.type = *showWindowMenuAtom;
xev.sequence = 0; xev.sequence = 0;
xev.window = window->winId(); xev.window = widget->winId();
xev.format = 32; xev.format = 32;
xev.data.data32[0] = 0; xev.data.data32[0] = 0;
xev.data.data32[1] = globalPos.x(); xev.data.data32[1] = globalPos.x();
@ -384,8 +391,6 @@ bool ShowXCBWindowMenu(QWindow *window) {
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
| XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY,
reinterpret_cast<const char*>(&xev)); reinterpret_cast<const char*>(&xev));
return true;
} }
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION #endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
@ -513,39 +518,34 @@ bool WindowExtentsSupported() {
return false; return false;
} }
void SetWindowExtents(QWindow *window, const QMargins &extents) { void SetWindowExtents(not_null<QWidget*> widget, const QMargins &extents) {
const auto nativeExtents = extents * window->devicePixelRatio();
if (const auto integration = WaylandIntegration::Instance()) { if (const auto integration = WaylandIntegration::Instance()) {
integration->setWindowExtents(window, nativeExtents); integration->setWindowExtents(widget, extents);
} else if (::Platform::IsX11()) { } else if (::Platform::IsX11()) {
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION #ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
SetXCBFrameExtents(window, nativeExtents); SetXCBFrameExtents(widget, extents);
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION #endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
} }
} }
void UnsetWindowExtents(QWindow *window) { void UnsetWindowExtents(not_null<QWidget*> widget) {
if (const auto integration = WaylandIntegration::Instance()) { if (const auto integration = WaylandIntegration::Instance()) {
integration->unsetWindowExtents(window); integration->unsetWindowExtents(widget);
} else if (::Platform::IsX11()) { } else if (::Platform::IsX11()) {
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION #ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
UnsetXCBFrameExtents(window); UnsetXCBFrameExtents(widget);
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION #endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
} }
} }
bool ShowWindowMenu(QWindow *window) { void ShowWindowMenu(not_null<QWidget*> widget, const QPoint &point) {
if (const auto integration = WaylandIntegration::Instance()) { if (const auto integration = WaylandIntegration::Instance()) {
return integration->showWindowMenu(window); integration->showWindowMenu(widget, point);
} else if (::Platform::IsX11()) { } else if (::Platform::IsX11()) {
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION #ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
return ShowXCBWindowMenu(window); ShowXCBWindowMenu(widget, point);
#else // !DESKTOP_APP_DISABLE_X11_INTEGRATION #endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
return false;
#endif // DESKTOP_APP_DISABLE_X11_INTEGRATION
} }
return false;
} }
TitleControls::Layout TitleControlsLayout() { TitleControls::Layout TitleControlsLayout() {

View file

@ -31,14 +31,13 @@ inline bool WindowExtentsSupported() {
return false; return false;
} }
inline void SetWindowExtents(QWindow *window, const QMargins &extents) { inline void SetWindowExtents(not_null<QWidget*> widget, const QMargins &extents) {
} }
inline void UnsetWindowExtents(QWindow *window) { inline void UnsetWindowExtents(not_null<QWidget*> widget) {
} }
inline bool ShowWindowMenu(QWindow *window) { inline void ShowWindowMenu(not_null<QWidget*> widget, const QPoint &point) {
return false;
} }
} // namespace Platform } // namespace Platform

View file

@ -39,9 +39,9 @@ void DisableSystemWindowResize(not_null<QWidget*> widget, QSize ratio);
void DrainMainQueue(); // Needed only if UseMainQueueGeneric() is false. void DrainMainQueue(); // Needed only if UseMainQueueGeneric() is false.
[[nodiscard]] bool WindowExtentsSupported(); [[nodiscard]] bool WindowExtentsSupported();
void SetWindowExtents(QWindow *window, const QMargins &extents); void SetWindowExtents(not_null<QWidget*> widget, const QMargins &extents);
void UnsetWindowExtents(QWindow *window); void UnsetWindowExtents(not_null<QWidget*> widget);
bool ShowWindowMenu(QWindow *window); void ShowWindowMenu(not_null<QWidget*> widget, const QPoint &point);
[[nodiscard]] TitleControls::Layout TitleControlsLayout(); [[nodiscard]] TitleControls::Layout TitleControlsLayout();
[[nodiscard]] rpl::producer<TitleControls::Layout> TitleControlsLayoutValue(); [[nodiscard]] rpl::producer<TitleControls::Layout> TitleControlsLayoutValue();

View file

@ -491,10 +491,10 @@ void DefaultWindowHelper::paintBorders(QPainter &p) {
void DefaultWindowHelper::updateWindowExtents() { void DefaultWindowHelper::updateWindowExtents() {
if (hasShadow() && !_title->isHidden()) { if (hasShadow() && !_title->isHidden()) {
SetWindowExtents(window()->windowHandle(), resizeArea()); SetWindowExtents(window(), resizeArea());
_extentsSet = true; _extentsSet = true;
} else if (_extentsSet) { } else if (_extentsSet) {
UnsetWindowExtents(window()->windowHandle()); UnsetWindowExtents(window());
_extentsSet = false; _extentsSet = false;
} }
} }

View file

@ -450,7 +450,7 @@ void DefaultTitleWidget::mousePressEvent(QMouseEvent *e) {
if (e->button() == Qt::LeftButton) { if (e->button() == Qt::LeftButton) {
_mousePressed = true; _mousePressed = true;
} else if (e->button() == Qt::RightButton) { } else if (e->button() == Qt::RightButton) {
ShowWindowMenu(window()->windowHandle()); ShowWindowMenu(window(), e->windowPos().toPoint());
} }
} }

View file

@ -9,7 +9,6 @@
#include "base/platform/win/base_windows_h.h" #include "base/platform/win/base_windows_h.h"
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
#include <QtGui/QWindow>
#include <wrl/client.h> #include <wrl/client.h>
#include <Shobjidl.h> #include <Shobjidl.h>
@ -121,16 +120,16 @@ std::optional<bool> IsOverlapped(
return false; return false;
} }
bool ShowWindowMenu(QWindow *window) { void ShowWindowMenu(not_null<QWidget*> widget, const QPoint &point) {
const auto pos = QCursor::pos(); const auto handle = HWND(widget->winId());
const auto mapped = point * widget->devicePixelRatioF();
POINT p{ mapped.x(), mapped.y() };
ClientToScreen(handle, &p);
SendMessage( SendMessage(
HWND(window->winId()), handle,
0x313 /* WM_POPUPSYSTEMMENU */, 0x313 /* WM_POPUPSYSTEMMENU */,
0, 0,
MAKELPARAM(pos.x(), pos.y())); MAKELPARAM(p.x, p.y));
return true;
} }
TitleControls::Layout TitleControlsLayout() { TitleControls::Layout TitleControlsLayout() {

View file

@ -49,10 +49,10 @@ inline bool WindowExtentsSupported() {
return false; return false;
} }
inline void SetWindowExtents(QWindow *window, const QMargins &extents) { inline void SetWindowExtents(not_null<QWidget*> widget, const QMargins &extents) {
} }
inline void UnsetWindowExtents(QWindow *window) { inline void UnsetWindowExtents(not_null<QWidget*> widget) {
} }
} // namespace Platform } // namespace Platform

View file

@ -8,6 +8,7 @@
#include "ui/inactive_press.h" #include "ui/inactive_press.h"
#include "ui/platform/win/ui_window_title_win.h" #include "ui/platform/win/ui_window_title_win.h"
#include "ui/platform/ui_platform_utility.h"
#include "ui/widgets/rp_window.h" #include "ui/widgets/rp_window.h"
#include "ui/painter.h" #include "ui/painter.h"
#include "base/platform/win/base_windows_safe_library.h" #include "base/platform/win/base_windows_safe_library.h"
@ -569,7 +570,10 @@ bool WindowHelper::handleNativeEvent(
if (_title->isHidden() && !frameMarginsSet()) { if (_title->isHidden() && !frameMarginsSet()) {
return false; return false;
} }
SendMessage(_handle, 0x313 /* WM_POPUPSYSTEMMENU */, 0, lParam); POINT p{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
ScreenToClient(_handle, &p);
const auto mapped = QPoint(p.x, p.y) / window()->devicePixelRatioF();
ShowWindowMenu(window(), mapped);
if (result) *result = 0; if (result) *result = 0;
} return true; } return true;