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

View file

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

View file

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

View file

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

View file

@ -31,14 +31,13 @@ inline bool WindowExtentsSupported() {
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) {
return false;
inline void ShowWindowMenu(not_null<QWidget*> widget, const QPoint &point) {
}
} // namespace Platform

View file

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

View file

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

View file

@ -450,7 +450,7 @@ void DefaultTitleWidget::mousePressEvent(QMouseEvent *e) {
if (e->button() == Qt::LeftButton) {
_mousePressed = true;
} 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 <QtWidgets/QApplication>
#include <QtGui/QWindow>
#include <wrl/client.h>
#include <Shobjidl.h>
@ -121,16 +120,16 @@ std::optional<bool> IsOverlapped(
return false;
}
bool ShowWindowMenu(QWindow *window) {
const auto pos = QCursor::pos();
void ShowWindowMenu(not_null<QWidget*> widget, const QPoint &point) {
const auto handle = HWND(widget->winId());
const auto mapped = point * widget->devicePixelRatioF();
POINT p{ mapped.x(), mapped.y() };
ClientToScreen(handle, &p);
SendMessage(
HWND(window->winId()),
handle,
0x313 /* WM_POPUPSYSTEMMENU */,
0,
MAKELPARAM(pos.x(), pos.y()));
return true;
MAKELPARAM(p.x, p.y));
}
TitleControls::Layout TitleControlsLayout() {

View file

@ -49,10 +49,10 @@ inline bool WindowExtentsSupported() {
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

View file

@ -8,6 +8,7 @@
#include "ui/inactive_press.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/painter.h"
#include "base/platform/win/base_windows_safe_library.h"
@ -569,7 +570,10 @@ bool WindowHelper::handleNativeEvent(
if (_title->isHidden() && !frameMarginsSet()) {
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;
} return true;