mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-07 15:43:55 +02:00
Add support for custom titlebar on Linux with Qt < 5.15
This commit is contained in:
parent
2fd5771c3d
commit
b587328fed
8 changed files with 217 additions and 15 deletions
|
@ -127,6 +127,16 @@ PRIVATE
|
||||||
desktop-app::external_openal
|
desktop-app::external_openal
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (LINUX AND DESKTOP_APP_USE_PACKAGED)
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(WAYLAND_CLIENT REQUIRED wayland-client)
|
||||||
|
|
||||||
|
target_include_directories(Telegram
|
||||||
|
PRIVATE
|
||||||
|
${WAYLAND_CLIENT_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (LINUX)
|
if (LINUX)
|
||||||
if (DESKTOP_APP_USE_PACKAGED)
|
if (DESKTOP_APP_USE_PACKAGED)
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
|
|
|
@ -24,8 +24,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include <QtCore/QStandardPaths>
|
#include <QtCore/QStandardPaths>
|
||||||
#include <QtCore/QProcess>
|
#include <QtCore/QProcess>
|
||||||
#include <QtCore/QVersionNumber>
|
#include <QtCore/QVersionNumber>
|
||||||
|
#include <QtGui/QWindow>
|
||||||
#include <qpa/qplatformnativeinterface.h>
|
#include <qpa/qplatformnativeinterface.h>
|
||||||
|
|
||||||
|
#include <private/qwaylanddisplay_p.h>
|
||||||
|
#include <private/qwaylandwindow_p.h>
|
||||||
|
#include <private/qwaylandshellsurface_p.h>
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
#ifndef TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||||
#include <QtDBus/QDBusInterface>
|
#include <QtDBus/QDBusInterface>
|
||||||
#include <QtDBus/QDBusConnection>
|
#include <QtDBus/QDBusConnection>
|
||||||
|
@ -36,6 +41,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/screensaver.h>
|
#include <xcb/screensaver.h>
|
||||||
|
#include <wayland-client.h>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -48,6 +54,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
using namespace Platform;
|
using namespace Platform;
|
||||||
using Platform::File::internal::EscapeShell;
|
using Platform::File::internal::EscapeShell;
|
||||||
|
using QtWaylandClient::QWaylandWindow;
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -394,6 +401,144 @@ std::optional<crl::time> MutterDBusLastUserInputTime() {
|
||||||
}
|
}
|
||||||
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
#endif // !TDESKTOP_DISABLE_DBUS_INTEGRATION
|
||||||
|
|
||||||
|
uint XCBMoveResizeFromEdges(Qt::Edges edges) {
|
||||||
|
if (edges == (Qt::TopEdge | Qt::LeftEdge))
|
||||||
|
return 0;
|
||||||
|
if (edges == Qt::TopEdge)
|
||||||
|
return 1;
|
||||||
|
if (edges == (Qt::TopEdge | Qt::RightEdge))
|
||||||
|
return 2;
|
||||||
|
if (edges == Qt::RightEdge)
|
||||||
|
return 3;
|
||||||
|
if (edges == (Qt::RightEdge | Qt::BottomEdge))
|
||||||
|
return 4;
|
||||||
|
if (edges == Qt::BottomEdge)
|
||||||
|
return 5;
|
||||||
|
if (edges == (Qt::BottomEdge | Qt::LeftEdge))
|
||||||
|
return 6;
|
||||||
|
if (edges == Qt::LeftEdge)
|
||||||
|
return 7;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum wl_shell_surface_resize WlResizeFromEdges(Qt::Edges edges) {
|
||||||
|
if (edges == (Qt::TopEdge | Qt::LeftEdge))
|
||||||
|
return WL_SHELL_SURFACE_RESIZE_TOP_LEFT;
|
||||||
|
if (edges == Qt::TopEdge)
|
||||||
|
return WL_SHELL_SURFACE_RESIZE_TOP;
|
||||||
|
if (edges == (Qt::TopEdge | Qt::RightEdge))
|
||||||
|
return WL_SHELL_SURFACE_RESIZE_TOP_RIGHT;
|
||||||
|
if (edges == Qt::RightEdge)
|
||||||
|
return WL_SHELL_SURFACE_RESIZE_RIGHT;
|
||||||
|
if (edges == (Qt::RightEdge | Qt::BottomEdge))
|
||||||
|
return WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT;
|
||||||
|
if (edges == Qt::BottomEdge)
|
||||||
|
return WL_SHELL_SURFACE_RESIZE_BOTTOM;
|
||||||
|
if (edges == (Qt::BottomEdge | Qt::LeftEdge))
|
||||||
|
return WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT;
|
||||||
|
if (edges == Qt::LeftEdge)
|
||||||
|
return WL_SHELL_SURFACE_RESIZE_LEFT;
|
||||||
|
|
||||||
|
return WL_SHELL_SURFACE_RESIZE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StartXCBMoveResize(QWindow *window, int edges) {
|
||||||
|
const auto native = QGuiApplication::platformNativeInterface();
|
||||||
|
|
||||||
|
if (!native) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto connection = reinterpret_cast<xcb_connection_t*>(
|
||||||
|
native->nativeResourceForIntegration(QByteArray("connection")));
|
||||||
|
|
||||||
|
if (!connection) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto screen = xcb_setup_roots_iterator(
|
||||||
|
xcb_get_setup(connection)).data;
|
||||||
|
|
||||||
|
if (!screen) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto moveResizeCookie = xcb_intern_atom(connection,
|
||||||
|
0,
|
||||||
|
strlen("_NET_WM_MOVERESIZE"),
|
||||||
|
"_NET_WM_MOVERESIZE");
|
||||||
|
|
||||||
|
auto moveResizeReply = xcb_intern_atom_reply(
|
||||||
|
connection,
|
||||||
|
moveResizeCookie,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
if (!moveResizeReply) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto moveResize = moveResizeReply->atom;
|
||||||
|
free(moveResizeReply);
|
||||||
|
|
||||||
|
const auto globalPos = QCursor::pos();
|
||||||
|
|
||||||
|
xcb_client_message_event_t xev;
|
||||||
|
xev.response_type = XCB_CLIENT_MESSAGE;
|
||||||
|
xev.type = moveResize;
|
||||||
|
xev.sequence = 0;
|
||||||
|
xev.window = window->winId();
|
||||||
|
xev.format = 32;
|
||||||
|
xev.data.data32[0] = globalPos.x();
|
||||||
|
xev.data.data32[1] = globalPos.y();
|
||||||
|
xev.data.data32[2] = (edges == 16)
|
||||||
|
? 8 // move
|
||||||
|
: XCBMoveResizeFromEdges(Qt::Edges(edges));
|
||||||
|
xev.data.data32[3] = XCB_BUTTON_INDEX_1;
|
||||||
|
xev.data.data32[4] = 0;
|
||||||
|
|
||||||
|
xcb_ungrab_pointer(connection, XCB_CURRENT_TIME);
|
||||||
|
xcb_send_event(connection,
|
||||||
|
false,
|
||||||
|
screen->root,
|
||||||
|
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY,
|
||||||
|
reinterpret_cast<const char*>(&xev));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StartWaylandMove(QWindow *window) {
|
||||||
|
if (const auto waylandWindow = static_cast<QWaylandWindow*>(window->handle())) {
|
||||||
|
if (const auto seat = waylandWindow->display()->lastInputDevice()) {
|
||||||
|
if (const auto shellSurface = waylandWindow->shellSurface()) {
|
||||||
|
return shellSurface->move(seat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StartWaylandResize(QWindow *window, Qt::Edges edges) {
|
||||||
|
if (const auto waylandWindow = static_cast<QWaylandWindow*>(window->handle())) {
|
||||||
|
if (const auto seat = waylandWindow->display()->lastInputDevice()) {
|
||||||
|
if (const auto shellSurface = waylandWindow->shellSurface()) {
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
|
||||||
|
return shellSurface->resize(seat, edges);
|
||||||
|
#elif QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) || defined DESKTOP_APP_QT_PATCHED // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
||||||
|
shellSurface->resize(seat, edges);
|
||||||
|
return true;
|
||||||
|
#else // Qt >= 5.13 || DESKTOP_APP_QT_PATCHED
|
||||||
|
shellSurface->resize(seat, WlResizeFromEdges(edges));
|
||||||
|
return true;
|
||||||
|
#endif // Qt < 5.13 && !DESKTOP_APP_QT_PATCHED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void SetApplicationIcon(const QIcon &icon) {
|
void SetApplicationIcon(const QIcon &icon) {
|
||||||
|
@ -745,6 +890,22 @@ void FallbackFontConfigCheckEnd() {
|
||||||
QFile(FallbackFontConfigCheckPath()).remove();
|
QFile(FallbackFontConfigCheckPath()).remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StartSystemMove(QWindow *window) {
|
||||||
|
if (IsWayland()) {
|
||||||
|
return StartWaylandMove(window);
|
||||||
|
} else {
|
||||||
|
return StartXCBMoveResize(window, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StartSystemResize(QWindow *window, Qt::Edges edges) {
|
||||||
|
if (IsWayland()) {
|
||||||
|
return StartWaylandResize(window, edges);
|
||||||
|
} else {
|
||||||
|
return StartXCBMoveResize(window, edges);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Platform
|
} // namespace Platform
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "platform/platform_window_title.h"
|
#include "platform/platform_window_title.h"
|
||||||
#include "platform/linux/linux_desktop_environment.h"
|
|
||||||
#include "base/object_ptr.h"
|
#include "base/object_ptr.h"
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
@ -23,17 +22,11 @@ void DefaultPreviewWindowFramePaint(QImage &preview, const style::palette &palet
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
|
||||||
inline bool AllowNativeWindowFrameToggle() {
|
inline bool AllowNativeWindowFrameToggle() {
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
|
return true;
|
||||||
return !DesktopEnvironment::IsUnity();
|
|
||||||
#else // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
|
||||||
return false;
|
|
||||||
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
|
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
|
||||||
return AllowNativeWindowFrameToggle()
|
return object_ptr<Window::TitleWidgetQt>(parent);
|
||||||
? object_ptr<Window::TitleWidgetQt>(parent)
|
|
||||||
: object_ptr<Window::TitleWidgetQt>{ nullptr };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool NativeTitleRequiresShadow() {
|
inline bool NativeTitleRequiresShadow() {
|
||||||
|
|
|
@ -28,6 +28,14 @@ inline QImage GetImageFromClipboard() {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool StartSystemMove(QWindow *window) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool StartSystemResize(QWindow *window, Qt::Edges edges) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ThirdParty {
|
namespace ThirdParty {
|
||||||
|
|
||||||
inline void start() {
|
inline void start() {
|
||||||
|
|
|
@ -44,6 +44,8 @@ bool OpenSystemSettings(SystemSettingsType type);
|
||||||
void IgnoreApplicationActivationRightNow();
|
void IgnoreApplicationActivationRightNow();
|
||||||
bool AutostartSupported();
|
bool AutostartSupported();
|
||||||
QImage GetImageFromClipboard();
|
QImage GetImageFromClipboard();
|
||||||
|
bool StartSystemMove(QWindow *window);
|
||||||
|
bool StartSystemResize(QWindow *window, Qt::Edges edges);
|
||||||
|
|
||||||
namespace ThirdParty {
|
namespace ThirdParty {
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,14 @@ inline QImage GetImageFromClipboard() {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool StartSystemMove(QWindow *window) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool StartSystemResize(QWindow *window, Qt::Edges edges) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ThirdParty {
|
namespace ThirdParty {
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "window/window_title_qt.h"
|
#include "window/window_title_qt.h"
|
||||||
|
|
||||||
|
#include "platform/platform_specific.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
|
@ -121,9 +122,7 @@ void TitleWidgetQt::mousePressEvent(QMouseEvent *e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
|
startMove();
|
||||||
window()->windowHandle()->startSystemMove();
|
|
||||||
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TitleWidgetQt::mouseDoubleClickEvent(QMouseEvent *e) {
|
void TitleWidgetQt::mouseDoubleClickEvent(QMouseEvent *e) {
|
||||||
|
@ -260,14 +259,34 @@ void TitleWidgetQt::updateCursor(Qt::Edges edges) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TitleWidgetQt::startResize(Qt::Edges edges) {
|
bool TitleWidgetQt::startMove() {
|
||||||
|
if (Platform::StartSystemMove(window()->windowHandle())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
|
||||||
if (edges) {
|
if (window()->windowHandle()->startSystemMove()) {
|
||||||
return window()->windowHandle()->startSystemResize(edges);
|
return true;
|
||||||
}
|
}
|
||||||
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TitleWidgetQt::startResize(Qt::Edges edges) {
|
||||||
|
if (edges) {
|
||||||
|
if (Platform::StartSystemResize(window()->windowHandle(), edges)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
|
||||||
|
if (window()->windowHandle()->startSystemResize(edges)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
|
@ -45,6 +45,7 @@ private:
|
||||||
Qt::Edges edgesFromPos(const QPoint &pos);
|
Qt::Edges edgesFromPos(const QPoint &pos);
|
||||||
void updateCursor(Qt::Edges edges);
|
void updateCursor(Qt::Edges edges);
|
||||||
void restoreCursor();
|
void restoreCursor();
|
||||||
|
bool startMove();
|
||||||
bool startResize(Qt::Edges edges);
|
bool startResize(Qt::Edges edges);
|
||||||
|
|
||||||
const style::WindowTitle &_st;
|
const style::WindowTitle &_st;
|
||||||
|
|
Loading…
Add table
Reference in a new issue