Updated TDesktop sources to 2.3.2+2de0ebc

This commit is contained in:
Eric Kotato 2020-08-30 16:22:15 +03:00
commit 97341e102d
16 changed files with 546 additions and 203 deletions

View file

@ -163,7 +163,6 @@ if (LINUX)
) )
target_compile_definitions(Telegram PRIVATE G_LOG_DOMAIN="Kotatogram") target_compile_definitions(Telegram PRIVATE G_LOG_DOMAIN="Kotatogram")
target_compile_options(Telegram PRIVATE -Wno-register)
if (NOT TDESKTOP_DISABLE_GTK_INTEGRATION) if (NOT TDESKTOP_DISABLE_GTK_INTEGRATION)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)

View file

@ -39,6 +39,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h" #include "apiwrap.h"
#include "api/api_updates.h" #include "api/api_updates.h"
#include "settings/settings_intro.h" #include "settings/settings_intro.h"
#include "platform/platform_specific.h"
#include "platform/platform_notifications_manager.h" #include "platform/platform_notifications_manager.h"
#include "base/platform/base_platform_info.h" #include "base/platform/base_platform_info.h"
#include "base/call_delayed.h" #include "base/call_delayed.h"
@ -102,7 +103,12 @@ MainWindow::MainWindow(not_null<Window::Controller*> controller)
}, lifetime()); }, lifetime());
setAttribute(Qt::WA_NoSystemBackground); setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_OpaquePaintEvent);
if (Platform::WindowsNeedShadow()) {
setAttribute(Qt::WA_TranslucentBackground);
} else {
setAttribute(Qt::WA_OpaquePaintEvent);
}
} }
void MainWindow::initHook() { void MainWindow::initHook() {
@ -761,7 +767,9 @@ void MainWindow::handleTrayIconActication(
} }
if (reason == QSystemTrayIcon::Context) { if (reason == QSystemTrayIcon::Context) {
updateTrayMenu(true); updateTrayMenu(true);
QTimer::singleShot(1, this, SLOT(psShowTrayMenu())); base::call_delayed(1, this, [=] {
psShowTrayMenu();
});
} else if (!skipTrayClick()) { } else if (!skipTrayClick()) {
if (Platform::IsWayland() ? isVisible() : isActive()) { if (Platform::IsWayland() ? isVisible() : isActive()) {
minimizeToTray(); minimizeToTray();

View file

@ -467,7 +467,12 @@ void MainWindow::initHook() {
sniWatcher, sniWatcher,
&QDBusServiceWatcher::serviceOwnerChanged, &QDBusServiceWatcher::serviceOwnerChanged,
this, this,
&MainWindow::onSNIOwnerChanged); [=](
const QString &service,
const QString &oldOwner,
const QString &newOwner) {
handleSNIOwnerChanged(service, oldOwner, newOwner);
});
AppMenuSupported = IsAppMenuSupported(); AppMenuSupported = IsAppMenuSupported();
@ -481,13 +486,18 @@ void MainWindow::initHook() {
appMenuWatcher, appMenuWatcher,
&QDBusServiceWatcher::serviceOwnerChanged, &QDBusServiceWatcher::serviceOwnerChanged,
this, this,
&MainWindow::onAppMenuOwnerChanged); [=](
const QString &service,
const QString &oldOwner,
const QString &newOwner) {
handleAppMenuOwnerChanged(service, oldOwner, newOwner);
});
connect( connect(
windowHandle(), windowHandle(),
&QWindow::visibleChanged, &QWindow::visibleChanged,
this, this,
&MainWindow::onVisibleChanged); [=](bool visible) { handleVisibleChanged(visible); });
if (AppMenuSupported) { if (AppMenuSupported) {
LOG(("Using D-Bus global menu.")); LOG(("Using D-Bus global menu."));
@ -591,7 +601,7 @@ void MainWindow::attachToSNITrayIcon() {
updateTrayMenu(); updateTrayMenu();
} }
void MainWindow::onSNIOwnerChanged( void MainWindow::handleSNIOwnerChanged(
const QString &service, const QString &service,
const QString &oldOwner, const QString &oldOwner,
const QString &newOwner) { const QString &newOwner) {
@ -627,7 +637,7 @@ void MainWindow::onSNIOwnerChanged(
} }
} }
void MainWindow::onAppMenuOwnerChanged( void MainWindow::handleAppMenuOwnerChanged(
const QString &service, const QString &service,
const QString &oldOwner, const QString &oldOwner,
const QString &newOwner) { const QString &newOwner) {
@ -804,7 +814,7 @@ void MainWindow::createGlobalMenu() {
auto quit = file->addAction( auto quit = file->addAction(
tr::lng_mac_menu_quit_telegram(tr::now, lt_telegram, qsl("Kotatogram")), tr::lng_mac_menu_quit_telegram(tr::now, lt_telegram, qsl("Kotatogram")),
App::wnd(), App::wnd(),
SLOT(quitFromTray()), [=] { App::wnd()->quitFromTray(); },
QKeySequence::Quit); QKeySequence::Quit);
quit->setMenuRole(QAction::QuitRole); quit->setMenuRole(QAction::QuitRole);
@ -814,13 +824,13 @@ void MainWindow::createGlobalMenu() {
psUndo = edit->addAction( psUndo = edit->addAction(
tr::lng_linux_menu_undo(tr::now), tr::lng_linux_menu_undo(tr::now),
this, this,
SLOT(psLinuxUndo()), [=] { psLinuxUndo(); },
QKeySequence::Undo); QKeySequence::Undo);
psRedo = edit->addAction( psRedo = edit->addAction(
tr::lng_linux_menu_redo(tr::now), tr::lng_linux_menu_redo(tr::now),
this, this,
SLOT(psLinuxRedo()), [=] { psLinuxRedo(); },
QKeySequence::Redo); QKeySequence::Redo);
edit->addSeparator(); edit->addSeparator();
@ -828,24 +838,24 @@ void MainWindow::createGlobalMenu() {
psCut = edit->addAction( psCut = edit->addAction(
tr::lng_mac_menu_cut(tr::now), tr::lng_mac_menu_cut(tr::now),
this, this,
SLOT(psLinuxCut()), [=] { psLinuxCut(); },
QKeySequence::Cut); QKeySequence::Cut);
psCopy = edit->addAction( psCopy = edit->addAction(
tr::lng_mac_menu_copy(tr::now), tr::lng_mac_menu_copy(tr::now),
this, this,
SLOT(psLinuxCopy()), [=] { psLinuxCopy(); },
QKeySequence::Copy); QKeySequence::Copy);
psPaste = edit->addAction( psPaste = edit->addAction(
tr::lng_mac_menu_paste(tr::now), tr::lng_mac_menu_paste(tr::now),
this, this,
SLOT(psLinuxPaste()), [=] { psLinuxPaste(); },
QKeySequence::Paste); QKeySequence::Paste);
psDelete = edit->addAction( psDelete = edit->addAction(
tr::lng_mac_menu_delete(tr::now), tr::lng_mac_menu_delete(tr::now),
this, this,
SLOT(psLinuxDelete()), [=] { psLinuxDelete(); },
QKeySequence(Qt::ControlModifier | Qt::Key_Backspace)); QKeySequence(Qt::ControlModifier | Qt::Key_Backspace));
edit->addSeparator(); edit->addSeparator();
@ -853,44 +863,44 @@ void MainWindow::createGlobalMenu() {
psBold = edit->addAction( psBold = edit->addAction(
tr::lng_menu_formatting_bold(tr::now), tr::lng_menu_formatting_bold(tr::now),
this, this,
SLOT(psLinuxBold()), [=] { psLinuxBold(); },
QKeySequence::Bold); QKeySequence::Bold);
psItalic = edit->addAction( psItalic = edit->addAction(
tr::lng_menu_formatting_italic(tr::now), tr::lng_menu_formatting_italic(tr::now),
this, this,
SLOT(psLinuxItalic()), [=] { psLinuxItalic(); },
QKeySequence::Italic); QKeySequence::Italic);
psUnderline = edit->addAction( psUnderline = edit->addAction(
tr::lng_menu_formatting_underline(tr::now), tr::lng_menu_formatting_underline(tr::now),
this, this,
SLOT(psLinuxUnderline()), [=] { psLinuxUnderline(); },
QKeySequence::Underline); QKeySequence::Underline);
psStrikeOut = edit->addAction( psStrikeOut = edit->addAction(
tr::lng_menu_formatting_strike_out(tr::now), tr::lng_menu_formatting_strike_out(tr::now),
this, this,
SLOT(psLinuxStrikeOut()), [=] { psLinuxStrikeOut(); },
Ui::kStrikeOutSequence); Ui::kStrikeOutSequence);
psMonospace = edit->addAction( psMonospace = edit->addAction(
tr::lng_menu_formatting_monospace(tr::now), tr::lng_menu_formatting_monospace(tr::now),
this, this,
SLOT(psLinuxMonospace()), [=] { psLinuxMonospace(); },
Ui::kMonospaceSequence); Ui::kMonospaceSequence);
psClearFormat = edit->addAction( psClearFormat = edit->addAction(
tr::lng_menu_formatting_clear(tr::now), tr::lng_menu_formatting_clear(tr::now),
this, this,
SLOT(psLinuxClearFormat()), [=] { psLinuxClearFormat(); },
Ui::kClearFormatSequence); Ui::kClearFormatSequence);
edit->addSeparator(); edit->addSeparator();
psSelectAll = edit->addAction( psSelectAll = edit->addAction(
tr::lng_mac_menu_select_all(tr::now), tr::lng_mac_menu_select_all(tr::now),
this, SLOT(psLinuxSelectAll()), this, [=] { psLinuxSelectAll(); },
QKeySequence::SelectAll); QKeySequence::SelectAll);
edit->addSeparator(); edit->addSeparator();
@ -898,7 +908,7 @@ void MainWindow::createGlobalMenu() {
auto prefs = edit->addAction( auto prefs = edit->addAction(
tr::lng_mac_menu_preferences(tr::now), tr::lng_mac_menu_preferences(tr::now),
App::wnd(), App::wnd(),
SLOT(showSettings()), [=] { App::wnd()->showSettings(); },
QKeySequence(Qt::ControlModifier | Qt::Key_Comma)); QKeySequence(Qt::ControlModifier | Qt::Key_Comma));
prefs->setMenuRole(QAction::PreferencesRole); prefs->setMenuRole(QAction::PreferencesRole);
@ -933,19 +943,19 @@ void MainWindow::createGlobalMenu() {
psAddContact = tools->addAction( psAddContact = tools->addAction(
tr::lng_mac_menu_add_contact(tr::now), tr::lng_mac_menu_add_contact(tr::now),
App::wnd(), App::wnd(),
SLOT(onShowAddContact())); [=] { App::wnd()->onShowAddContact(); });
tools->addSeparator(); tools->addSeparator();
psNewGroup = tools->addAction( psNewGroup = tools->addAction(
tr::lng_mac_menu_new_group(tr::now), tr::lng_mac_menu_new_group(tr::now),
App::wnd(), App::wnd(),
SLOT(onShowNewGroup())); [=] { App::wnd()->onShowNewGroup(); });
psNewChannel = tools->addAction( psNewChannel = tools->addAction(
tr::lng_mac_menu_new_channel(tr::now), tr::lng_mac_menu_new_channel(tr::now),
App::wnd(), App::wnd(),
SLOT(onShowNewChannel())); [=] { App::wnd()->onShowNewChannel(); });
auto help = psMainMenu->addMenu(tr::lng_linux_menu_help(tr::now)); auto help = psMainMenu->addMenu(tr::lng_linux_menu_help(tr::now));
@ -1090,7 +1100,7 @@ void MainWindow::updateGlobalMenuHook() {
ForceDisabled(psClearFormat, !markdownEnabled); ForceDisabled(psClearFormat, !markdownEnabled);
} }
void MainWindow::onVisibleChanged(bool visible) { void MainWindow::handleVisibleChanged(bool visible) {
if (AppMenuSupported && !_mainMenuPath.path().isEmpty()) { if (AppMenuSupported && !_mainMenuPath.path().isEmpty()) {
if (visible) { if (visible) {
RegisterAppMenu(winId(), _mainMenuPath); RegisterAppMenu(winId(), _mainMenuPath);

View file

@ -21,8 +21,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Platform { namespace Platform {
class MainWindow : public Window::MainWindow { class MainWindow : public Window::MainWindow {
Q_OBJECT
public: public:
explicit MainWindow(not_null<Window::Controller*> controller); explicit MainWindow(not_null<Window::Controller*> controller);
@ -33,43 +31,12 @@ public:
style::color fg, style::color fg,
bool smallIcon) = 0; bool smallIcon) = 0;
void psShowTrayMenu();
static void LibsLoaded(); static void LibsLoaded();
~MainWindow(); ~MainWindow();
public slots:
void psShowTrayMenu();
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
void onSNIOwnerChanged(
const QString &service,
const QString &oldOwner,
const QString &newOwner);
void onAppMenuOwnerChanged(
const QString &service,
const QString &oldOwner,
const QString &newOwner);
void psLinuxUndo();
void psLinuxRedo();
void psLinuxCut();
void psLinuxCopy();
void psLinuxPaste();
void psLinuxDelete();
void psLinuxSelectAll();
void psLinuxBold();
void psLinuxItalic();
void psLinuxUnderline();
void psLinuxStrikeOut();
void psLinuxMonospace();
void psLinuxClearFormat();
void onVisibleChanged(bool visible);
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
protected: protected:
void initHook() override; void initHook() override;
void unreadCounterChangedHook() override; void unreadCounterChangedHook() override;
@ -100,6 +67,7 @@ private:
void updateIconCounters(); void updateIconCounters();
void updateWaylandDecorationColors(); void updateWaylandDecorationColors();
void handleVisibleChanged(bool visible);
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION #ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
StatusNotifierItem *_sniTrayIcon = nullptr; StatusNotifierItem *_sniTrayIcon = nullptr;
@ -131,6 +99,31 @@ private:
void setSNITrayIcon(int counter, bool muted); void setSNITrayIcon(int counter, bool muted);
void attachToSNITrayIcon(); void attachToSNITrayIcon();
void handleSNIOwnerChanged(
const QString &service,
const QString &oldOwner,
const QString &newOwner);
void handleAppMenuOwnerChanged(
const QString &service,
const QString &oldOwner,
const QString &newOwner);
void psLinuxUndo();
void psLinuxRedo();
void psLinuxCut();
void psLinuxCopy();
void psLinuxPaste();
void psLinuxDelete();
void psLinuxSelectAll();
void psLinuxBold();
void psLinuxItalic();
void psLinuxUnderline();
void psLinuxStrikeOut();
void psLinuxMonospace();
void psLinuxClearFormat();
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION #endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
}; };

View file

@ -81,6 +81,8 @@ constexpr auto kXDGDesktopPortalService = "org.freedesktop.portal.Desktop"_cs;
constexpr auto kXDGDesktopPortalObjectPath = "/org/freedesktop/portal/desktop"_cs; constexpr auto kXDGDesktopPortalObjectPath = "/org/freedesktop/portal/desktop"_cs;
constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs; constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs;
constexpr auto kXCBFrameExtentsAtomName = "_GTK_FRAME_EXTENTS"_cs;
QStringList PlatformThemes; QStringList PlatformThemes;
bool IsTrayIconSupported = true; bool IsTrayIconSupported = true;
@ -298,6 +300,105 @@ bool GetImageFromClipboardSupported() {
} }
#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION #endif // !TDESKTOP_DISABLE_GTK_INTEGRATION
std::optional<xcb_atom_t> GetXCBAtom(
xcb_connection_t *connection,
const QString &name) {
const auto cookie = xcb_intern_atom(
connection,
0,
name.size(),
name.toUtf8());
auto reply = xcb_intern_atom_reply(
connection,
cookie,
nullptr);
if (!reply) {
return std::nullopt;
}
const auto atom = reply->atom;
free(reply);
return atom;
}
bool IsXCBExtensionPresent(
xcb_connection_t *connection,
xcb_extension_t *ext) {
const auto reply = xcb_get_extension_data(
connection,
ext);
if (!reply) {
return false;
}
return reply->present;
}
std::vector<xcb_atom_t> GetXCBWMSupported(xcb_connection_t *connection) {
auto netWmAtoms = std::vector<xcb_atom_t>{};
const auto native = QGuiApplication::platformNativeInterface();
if (!native) {
return netWmAtoms;
}
const auto root = static_cast<xcb_window_t>(reinterpret_cast<quintptr>(
native->nativeResourceForIntegration(QByteArray("rootwindow"))));
const auto supportedAtom = GetXCBAtom(connection, "_NET_SUPPORTED");
if (!supportedAtom.has_value()) {
return netWmAtoms;
}
auto offset = 0;
auto remaining = 0;
do {
const auto cookie = xcb_get_property(
connection,
false,
root,
*supportedAtom,
XCB_ATOM_ATOM,
offset,
1024);
auto reply = xcb_get_property_reply(
connection,
cookie,
nullptr);
if (!reply) {
break;
}
remaining = 0;
if (reply->type == XCB_ATOM_ATOM && reply->format == 32) {
const auto len = xcb_get_property_value_length(reply)
/ sizeof(xcb_atom_t);
const auto atoms = reinterpret_cast<xcb_atom_t*>(
xcb_get_property_value(reply));
const auto s = netWmAtoms.size();
netWmAtoms.resize(s + len);
memcpy(netWmAtoms.data() + s, atoms, len * sizeof(xcb_atom_t));
remaining = reply->bytes_after;
offset += len;
}
free(reply);
} while (remaining > 0);
return netWmAtoms;
}
std::optional<crl::time> XCBLastUserInputTime() { std::optional<crl::time> XCBLastUserInputTime() {
const auto native = QGuiApplication::platformNativeInterface(); const auto native = QGuiApplication::platformNativeInterface();
if (!native) { if (!native) {
@ -311,24 +412,28 @@ std::optional<crl::time> XCBLastUserInputTime() {
return std::nullopt; return std::nullopt;
} }
const auto screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data; if (!IsXCBExtensionPresent(connection, &xcb_screensaver_id)) {
if (!screen) {
return std::nullopt; return std::nullopt;
} }
const auto cookie = xcb_screensaver_query_info(connection, screen->root); const auto root = static_cast<xcb_window_t>(reinterpret_cast<quintptr>(
native->nativeResourceForIntegration(QByteArray("rootwindow"))));
auto info = xcb_screensaver_query_info_reply( const auto cookie = xcb_screensaver_query_info(
connection,
root);
auto reply = xcb_screensaver_query_info_reply(
connection, connection,
cookie, cookie,
nullptr); nullptr);
if (!info) { if (!reply) {
return std::nullopt; return std::nullopt;
} }
const auto idle = info->ms_since_user_input; const auto idle = reply->ms_since_user_input;
free(info); free(reply);
return (crl::now() - static_cast<crl::time>(idle)); return (crl::now() - static_cast<crl::time>(idle));
} }
@ -391,7 +496,7 @@ std::optional<crl::time> MutterDBusLastUserInputTime() {
qsl("org.gnome.Mutter.IdleMonitor"), qsl("org.gnome.Mutter.IdleMonitor"),
qsl("GetIdletime")); qsl("GetIdletime"));
const QDBusReply<uint> reply = QDBusConnection::sessionBus().call( const QDBusReply<qulonglong> reply = QDBusConnection::sessionBus().call(
Message); Message);
static const auto NotSupportedErrors = { static const auto NotSupportedErrors = {
@ -468,7 +573,6 @@ enum wl_shell_surface_resize WlResizeFromEdges(Qt::Edges edges) {
bool StartXCBMoveResize(QWindow *window, int edges) { bool StartXCBMoveResize(QWindow *window, int edges) {
const auto native = QGuiApplication::platformNativeInterface(); const auto native = QGuiApplication::platformNativeInterface();
if (!native) { if (!native) {
return false; return false;
} }
@ -487,29 +591,16 @@ bool StartXCBMoveResize(QWindow *window, int edges) {
return false; return false;
} }
const auto moveResizeCookie = xcb_intern_atom( const auto moveResize = GetXCBAtom(connection, "_NET_WM_MOVERESIZE");
connection, if (!moveResize.has_value()) {
0,
strlen("_NET_WM_MOVERESIZE"),
"_NET_WM_MOVERESIZE");
auto moveResizeReply = xcb_intern_atom_reply(
connection,
moveResizeCookie,
nullptr);
if (!moveResizeReply) {
return false; return false;
} }
const auto moveResize = moveResizeReply->atom;
free(moveResizeReply);
const auto globalPos = QCursor::pos(); const auto globalPos = QCursor::pos();
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 = moveResize; xev.type = *moveResize;
xev.sequence = 0; xev.sequence = 0;
xev.window = window->winId(); xev.window = window->winId();
xev.format = 32; xev.format = 32;
@ -582,6 +673,116 @@ bool ShowWaylandWindowMenu(QWindow *window) {
return false; return false;
} }
bool XCBFrameExtentsSupported() {
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 frameExtentsAtom = GetXCBAtom(
connection,
kXCBFrameExtentsAtomName.utf16());
if (!frameExtentsAtom.has_value()) {
return false;
}
return ranges::contains(GetXCBWMSupported(connection), *frameExtentsAtom);
}
bool SetXCBFrameExtents(QWindow *window, const QMargins &extents) {
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 frameExtentsAtom = GetXCBAtom(
connection,
kXCBFrameExtentsAtomName.utf16());
if (!frameExtentsAtom.has_value()) {
return false;
}
const auto extentsVector = std::vector<uint>{
uint(extents.left()),
uint(extents.right()),
uint(extents.top()),
uint(extents.bottom()),
};
xcb_change_property(
connection,
XCB_PROP_MODE_REPLACE,
window->winId(),
*frameExtentsAtom,
XCB_ATOM_CARDINAL,
32,
extentsVector.size(),
extentsVector.data());
return true;
}
bool UnsetXCBFrameExtents(QWindow *window) {
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 frameExtentsAtom = GetXCBAtom(
connection,
kXCBFrameExtentsAtomName.utf16());
if (!frameExtentsAtom.has_value()) {
return false;
}
xcb_delete_property(
connection,
window->winId(),
*frameExtentsAtom);
return true;
}
bool SetWaylandWindowGeometry(QWindow *window, const QRect &geometry) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) || defined DESKTOP_APP_QT_PATCHED
if (const auto waylandWindow = static_cast<QWaylandWindow*>(
window->handle())) {
if (const auto seat = waylandWindow->display()->lastInputDevice()) {
if (const auto shellSurface = waylandWindow->shellSurface()) {
shellSurface->setWindowGeometry(geometry);
return true;
}
}
}
#endif // Qt >= 5.13 || DESKTOP_APP_QT_PATCHED
return false;
}
Window::Control GtkKeywordToWindowControl(const QString &keyword) { Window::Control GtkKeywordToWindowControl(const QString &keyword) {
if (keyword == qstr("minimize")) { if (keyword == qstr("minimize")) {
return Window::Control::Minimize; return Window::Control::Minimize;
@ -925,6 +1126,40 @@ bool ShowWindowMenu(QWindow *window) {
return false; return false;
} }
bool SetWindowExtents(QWindow *window, const QMargins &extents) {
if (IsWayland()) {
const auto geometry = QRect(QPoint(), window->size())
.marginsRemoved(extents);
return SetWaylandWindowGeometry(window, geometry);
} else {
return SetXCBFrameExtents(window, extents);
}
}
bool UnsetWindowExtents(QWindow *window) {
if (IsWayland()) {
const auto geometry = QRect(QPoint(), window->size());
return SetWaylandWindowGeometry(window, geometry);
} else {
return UnsetXCBFrameExtents(window);
}
}
bool WindowsNeedShadow() {
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) || defined DESKTOP_APP_QT_PATCHED
if (IsWayland()) {
return true;
}
#endif // Qt >= 5.13 || DESKTOP_APP_QT_PATCHED
if (!IsWayland() && XCBFrameExtentsSupported()) {
return true;
}
return false;
}
Window::ControlsLayout WindowControlsLayout() { Window::ControlsLayout WindowControlsLayout() {
#ifndef TDESKTOP_DISABLE_GTK_INTEGRATION #ifndef TDESKTOP_DISABLE_GTK_INTEGRATION
if (Libs::GtkSettingSupported() if (Libs::GtkSettingSupported()

View file

@ -35,11 +35,11 @@ public:
void updateWindowIcon() override; void updateWindowIcon() override;
void psShowTrayMenu();
class Private; class Private;
public slots: public slots:
void psShowTrayMenu();
void psMacUndo(); void psMacUndo();
void psMacRedo(); void psMacRedo();
void psMacCut(); void psMacCut();

View file

@ -46,6 +46,18 @@ inline bool TrayIconSupported() {
return true; return true;
} }
inline bool SetWindowExtents(QWindow *window, const QMargins &extents) {
return false;
}
inline bool UnsetWindowExtents(QWindow *window) {
return false;
}
inline bool WindowsNeedShadow() {
return false;
}
NSImage *ToNSImage(const QPixmap &pixmap); NSImage *ToNSImage(const QPixmap &pixmap);
namespace ThirdParty { namespace ThirdParty {

View file

@ -56,6 +56,9 @@ QImage GetImageFromClipboard();
bool StartSystemMove(QWindow *window); bool StartSystemMove(QWindow *window);
bool StartSystemResize(QWindow *window, Qt::Edges edges); bool StartSystemResize(QWindow *window, Qt::Edges edges);
bool ShowWindowMenu(QWindow *window); bool ShowWindowMenu(QWindow *window);
bool WindowsNeedShadow();
bool SetWindowExtents(QWindow *window, const QMargins &extents);
bool UnsetWindowExtents(QWindow *window);
Window::ControlsLayout WindowControlsLayout(); Window::ControlsLayout WindowControlsLayout();
namespace ThirdParty { namespace ThirdParty {

View file

@ -21,8 +21,6 @@ class PopupMenu;
namespace Platform { namespace Platform {
class MainWindow : public Window::MainWindow { class MainWindow : public Window::MainWindow {
Q_OBJECT
public: public:
explicit MainWindow(not_null<Window::Controller*> controller); explicit MainWindow(not_null<Window::Controller*> controller);
@ -58,11 +56,10 @@ public:
return _deltaTop; return _deltaTop;
} }
~MainWindow();
public slots:
void psShowTrayMenu(); void psShowTrayMenu();
~MainWindow();
protected: protected:
void initHook() override; void initHook() override;
int32 screenNameChecksum(const QString &name) const override; int32 screenNameChecksum(const QString &name) const override;

View file

@ -38,6 +38,18 @@ inline bool TrayIconSupported() {
return true; return true;
} }
inline bool SetWindowExtents(QWindow *window, const QMargins &extents) {
return false;
}
inline bool UnsetWindowExtents(QWindow *window) {
return false;
}
inline bool WindowsNeedShadow() {
return false;
}
namespace ThirdParty { namespace ThirdParty {
void start(); void start();

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "platform/platform_window_title.h" #include "platform/platform_window_title.h"
#include "base/platform/base_platform_info.h" #include "base/platform/base_platform_info.h"
#include "ui/platform/ui_platform_utility.h"
#include "history/history.h" #include "history/history.h"
#include "window/themes/window_theme.h" #include "window/themes/window_theme.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
@ -33,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "facades.h" #include "facades.h"
#include "app.h" #include "app.h"
#include "styles/style_window.h" #include "styles/style_window.h"
#include "styles/style_calls.h" // st::callShadow
#include <QtWidgets/QDesktopWidget> #include <QtWidgets/QDesktopWidget>
#include <QtCore/QMimeData> #include <QtCore/QMimeData>
@ -281,6 +283,8 @@ void MainWindow::init() {
void MainWindow::handleStateChanged(Qt::WindowState state) { void MainWindow::handleStateChanged(Qt::WindowState state) {
stateChangedHook(state); stateChangedHook(state);
updateShadowSize();
updateControlsGeometry();
if (state == Qt::WindowMinimized) { if (state == Qt::WindowMinimized) {
controller().updateIsActiveBlur(); controller().updateIsActiveBlur();
} else { } else {
@ -321,6 +325,17 @@ HitTestResult MainWindow::hitTest(const QPoint &p) const {
return Window::HitTestResult::None; return Window::HitTestResult::None;
} }
bool MainWindow::hasShadow() const {
const auto center = geometry().center();
return Platform::WindowsNeedShadow()
&& Ui::Platform::TranslucentWindowsSupported(center)
&& _title;
}
QRect MainWindow::inner() const {
return rect().marginsRemoved(_padding);
}
int MainWindow::computeMinWidth() const { int MainWindow::computeMinWidth() const {
auto result = st::windowMinWidth; auto result = st::windowMinWidth;
if (const auto session = _controller->sessionController()) { if (const auto session = _controller->sessionController()) {
@ -331,7 +346,7 @@ int MainWindow::computeMinWidth() const {
if (_rightColumn) { if (_rightColumn) {
result += _rightColumn->width(); result += _rightColumn->width();
} }
return result; return result + _padding.left() + _padding.right();
} }
int MainWindow::computeMinHeight() const { int MainWindow::computeMinHeight() const {
@ -340,10 +355,10 @@ int MainWindow::computeMinHeight() const {
if (!_outdated) { if (!_outdated) {
return 0; return 0;
} }
_outdated->resizeToWidth(st::windowMinWidth); _outdated->resizeToWidth(st::windowMinWidth - _padding.left() - _padding.right());
return _outdated->height(); return _outdated->height();
}(); }();
return title + outdated + st::windowMinHeight; return title + outdated + st::windowMinHeight + _padding.top() + _padding.bottom();
} }
void MainWindow::refreshTitleWidget() { void MainWindow::refreshTitleWidget() {
@ -366,7 +381,20 @@ void MainWindow::updateMinimumSize() {
setMinimumHeight(computeMinHeight()); setMinimumHeight(computeMinHeight());
} }
void MainWindow::updateShadowSize() {
_padding = hasShadow() && !isMaximized()
? st::callShadow.extend
: style::margins();
}
void MainWindow::recountGeometryConstraints() { void MainWindow::recountGeometryConstraints() {
#ifdef Q_OS_LINUX
const auto hasShadow = this->hasShadow();
setWindowFlag(Qt::NoDropShadowWindowHint, hasShadow);
setAttribute(Qt::WA_OpaquePaintEvent, !hasShadow);
#endif // Q_OS_LINUX
updateShadowSize();
updateMinimumSize(); updateMinimumSize();
updateControlsGeometry(); updateControlsGeometry();
fixOrder(); fixOrder();
@ -466,7 +494,15 @@ void MainWindow::attachToTrayIcon(not_null<QSystemTrayIcon*> icon) {
App::wnd()->updateTrayMenu(); App::wnd()->updateTrayMenu();
} }
void MainWindow::paintEvent(QPaintEvent *e) {
if (hasShadow() && !isMaximized()) {
QPainter p(this);
Ui::Shadow::paint(p, inner(), width(), st::callShadow);
}
}
void MainWindow::resizeEvent(QResizeEvent *e) { void MainWindow::resizeEvent(QResizeEvent *e) {
updateShadowSize();
updateControlsGeometry(); updateControlsGeometry();
} }
@ -479,27 +515,28 @@ void MainWindow::leaveEventHook(QEvent *e) {
} }
void MainWindow::updateControlsGeometry() { void MainWindow::updateControlsGeometry() {
auto bodyLeft = 0; const auto inner = this->inner();
auto bodyTop = 0; auto bodyLeft = inner.x();
auto bodyWidth = width(); auto bodyTop = inner.y();
auto bodyWidth = inner.width();
if (_title && !_title->isHidden()) { if (_title && !_title->isHidden()) {
_title->setGeometry(0, bodyTop, width(), _title->height()); _title->setGeometry(inner.x(), bodyTop, inner.width(), _title->height());
bodyTop += _title->height(); bodyTop += _title->height();
} }
if (_titleShadow) { if (_titleShadow) {
_titleShadow->setGeometry(0, bodyTop, width(), st::lineWidth); _titleShadow->setGeometry(inner.x(), bodyTop, inner.width(), st::lineWidth);
} }
if (_outdated) { if (_outdated) {
Ui::SendPendingMoveResizeEvents(_outdated.data()); Ui::SendPendingMoveResizeEvents(_outdated.data());
_outdated->resizeToWidth(width()); _outdated->resizeToWidth(inner.width());
_outdated->moveToLeft(0, bodyTop); _outdated->moveToLeft(inner.x(), bodyTop);
bodyTop += _outdated->height(); bodyTop += _outdated->height();
} }
if (_rightColumn) { if (_rightColumn) {
bodyWidth -= _rightColumn->width(); bodyWidth -= _rightColumn->width();
_rightColumn->setGeometry(bodyWidth, bodyTop, width() - bodyWidth, height() - bodyTop); _rightColumn->setGeometry(bodyWidth, bodyTop, inner.width() - bodyWidth, inner.height() - (bodyTop - inner.y()));
} }
_body->setGeometry(bodyLeft, bodyTop, bodyWidth, height() - bodyTop); _body->setGeometry(bodyLeft, bodyTop, bodyWidth, inner.height() - (bodyTop - inner.y()));
} }
void MainWindow::updateUnreadCounter() { void MainWindow::updateUnreadCounter() {
@ -629,12 +666,12 @@ void MainWindow::showRightColumn(object_ptr<TWidget> widget) {
int MainWindow::maximalExtendBy() const { int MainWindow::maximalExtendBy() const {
auto desktop = QDesktopWidget().availableGeometry(this); auto desktop = QDesktopWidget().availableGeometry(this);
return std::max(desktop.width() - geometry().width(), 0); return std::max(desktop.width() - inner().width(), 0);
} }
bool MainWindow::canExtendNoMove(int extendBy) const { bool MainWindow::canExtendNoMove(int extendBy) const {
auto desktop = QDesktopWidget().availableGeometry(this); auto desktop = QDesktopWidget().availableGeometry(this);
auto inner = geometry(); auto inner = geometry().marginsRemoved(_padding);
auto innerRight = (inner.x() + inner.width() + extendBy); auto innerRight = (inner.x() + inner.width() + extendBy);
auto desktopRight = (desktop.x() + desktop.width()); auto desktopRight = (desktop.x() + desktop.width());
return innerRight <= desktopRight; return innerRight <= desktopRight;

View file

@ -102,12 +102,15 @@ public:
void clearWidgets(); void clearWidgets();
QRect inner() const;
int computeMinWidth() const; int computeMinWidth() const;
int computeMinHeight() const; int computeMinHeight() const;
void recountGeometryConstraints(); void recountGeometryConstraints();
virtual void updateControlsGeometry(); virtual void updateControlsGeometry();
bool hasShadow() const;
public slots: public slots:
bool minimizeToTray(); bool minimizeToTray();
void updateGlobalMenu() { void updateGlobalMenu() {
@ -115,6 +118,7 @@ public slots:
} }
protected: protected:
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;
void leaveEventHook(QEvent *e) override; void leaveEventHook(QEvent *e) override;
@ -180,6 +184,7 @@ protected:
private: private:
void refreshTitleWidget(); void refreshTitleWidget();
void updateMinimumSize(); void updateMinimumSize();
void updateShadowSize();
void updatePalette(); void updatePalette();
void initSize(); void initSize();
@ -200,6 +205,7 @@ private:
bool _usingSupportIcon = false; bool _usingSupportIcon = false;
int _customIconId = 0; int _customIconId = 0;
QString _titleText; QString _titleText;
style::margins _padding;
bool _isActive = false; bool _isActive = false;

View file

@ -8,11 +8,14 @@ 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 "platform/platform_specific.h"
#include "base/platform/base_platform_info.h"
#include "ui/platform/ui_platform_utility.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/widgets/shadow.h" #include "ui/widgets/shadow.h"
#include "core/core_settings.h" #include "core/core_settings.h"
#include "core/application.h" #include "core/application.h"
#include "styles/style_window.h" #include "styles/style_window.h"
#include "styles/style_calls.h" // st::callShadow
#include "base/call_delayed.h" #include "base/call_delayed.h"
#include <QtGui/QGuiApplication> #include <QtGui/QGuiApplication>
@ -27,6 +30,10 @@ namespace {
// that window. If we show the window back with this delay it works. // that window. If we show the window back with this delay it works.
constexpr auto kShowAfterFramelessToggleDelay = crl::time(1000); constexpr auto kShowAfterFramelessToggleDelay = crl::time(1000);
style::margins ShadowExtents() {
return st::callShadow.extend;
}
} // namespace } // namespace
TitleWidgetQt::TitleWidgetQt(QWidget *parent) TitleWidgetQt::TitleWidgetQt(QWidget *parent)
@ -63,19 +70,29 @@ TitleWidgetQt::TitleWidgetQt(QWidget *parent)
QCoreApplication::instance()->installEventFilter(this); QCoreApplication::instance()->installEventFilter(this);
_windowWasFrameless = (window()->windowFlags() & Qt::FramelessWindowHint) != 0; _windowWasFrameless = (window()->windowFlags()
& Qt::FramelessWindowHint) != 0;
if (!_windowWasFrameless) { if (!_windowWasFrameless) {
toggleFramelessWindow(true); toggleFramelessWindow(true);
} }
setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_OpaquePaintEvent);
resize(width(), _st.height); resize(width(), _st.height);
updateWindowExtents();
} }
TitleWidgetQt::~TitleWidgetQt() { TitleWidgetQt::~TitleWidgetQt() {
restoreCursor(); restoreCursor();
if (!_windowWasFrameless) { if (!_windowWasFrameless) {
toggleFramelessWindow(false); toggleFramelessWindow(false);
} }
if (_extentsSet) {
Platform::UnsetWindowExtents(window()->windowHandle());
}
} }
void TitleWidgetQt::toggleFramelessWindow(bool enabled) { void TitleWidgetQt::toggleFramelessWindow(bool enabled) {
@ -98,11 +115,22 @@ void TitleWidgetQt::init() {
&QWindow::windowStateChanged, &QWindow::windowStateChanged,
this, this,
[=](Qt::WindowState state) { windowStateChanged(state); }); [=](Qt::WindowState state) { windowStateChanged(state); });
connect(
window()->windowHandle(),
&QWindow::visibleChanged,
this,
[=](bool visible) { visibleChanged(visible); });
_maximizedState = (window()->windowState() & Qt::WindowMaximized); _maximizedState = (window()->windowState() & Qt::WindowMaximized);
_activeState = isActiveWindow(); _activeState = isActiveWindow();
updateButtonsState(); updateButtonsState();
} }
bool TitleWidgetQt::hasShadow() const {
const auto center = window()->geometry().center();
return Platform::WindowsNeedShadow()
&& Ui::Platform::TranslucentWindowsSupported(center);
}
void TitleWidgetQt::paintEvent(QPaintEvent *e) { void TitleWidgetQt::paintEvent(QPaintEvent *e) {
auto active = isActiveWindow(); auto active = isActiveWindow();
if (_activeState != active) { if (_activeState != active) {
@ -112,6 +140,25 @@ void TitleWidgetQt::paintEvent(QPaintEvent *e) {
Painter(this).fillRect(rect(), active ? _st.bgActive : _st.bg); Painter(this).fillRect(rect(), active ? _st.bgActive : _st.bg);
} }
void TitleWidgetQt::updateWindowExtents() {
if (hasShadow()) {
if (!_maximizedState) {
Platform::SetWindowExtents(
window()->windowHandle(),
ShadowExtents());
} else {
Platform::SetWindowExtents(
window()->windowHandle(),
QMargins());
}
_extentsSet = true;
} else if (_extentsSet) {
Platform::UnsetWindowExtents(window()->windowHandle());
_extentsSet = false;
}
}
void TitleWidgetQt::updateControlsPosition() { void TitleWidgetQt::updateControlsPosition() {
const auto controlsLayout = Core::App().settings().windowControlsLayout(); const auto controlsLayout = Core::App().settings().windowControlsLayout();
const auto controlsLeft = controlsLayout.left; const auto controlsLeft = controlsLayout.left;
@ -197,7 +244,7 @@ void TitleWidgetQt::mousePressEvent(QMouseEvent *e) {
} }
void TitleWidgetQt::mouseDoubleClickEvent(QMouseEvent *e) { void TitleWidgetQt::mouseDoubleClickEvent(QMouseEvent *e) {
if (window()->windowState() == Qt::WindowMaximized) { if (_maximizedState) {
window()->setWindowState(Qt::WindowNoState); window()->setWindowState(Qt::WindowNoState);
} else { } else {
window()->setWindowState(Qt::WindowMaximized); window()->setWindowState(Qt::WindowMaximized);
@ -205,11 +252,20 @@ void TitleWidgetQt::mouseDoubleClickEvent(QMouseEvent *e) {
} }
bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) { bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) {
// I tried to listen only QEvent::Move and QEvent::Resize
// but that doesn't work on Wayland
if (obj->isWidgetType()
&& window() == static_cast<QWidget*>(obj)
&& Platform::IsWayland()) {
updateWindowExtents();
}
if (e->type() == QEvent::MouseMove if (e->type() == QEvent::MouseMove
|| e->type() == QEvent::MouseButtonPress) { || e->type() == QEvent::MouseButtonPress) {
if (window()->isAncestorOf(static_cast<QWidget*>(obj))) { if (window()->isAncestorOf(static_cast<QWidget*>(obj))) {
const auto mouseEvent = static_cast<QMouseEvent*>(e); const auto mouseEvent = static_cast<QMouseEvent*>(e);
const auto edges = edgesFromPos(mouseEvent->windowPos().toPoint()); const auto edges = edgesFromPos(
mouseEvent->windowPos().toPoint());
if (e->type() == QEvent::MouseMove if (e->type() == QEvent::MouseMove
&& mouseEvent->buttons() == Qt::NoButton) { && mouseEvent->buttons() == Qt::NoButton) {
@ -218,7 +274,7 @@ bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) {
if (e->type() == QEvent::MouseButtonPress if (e->type() == QEvent::MouseButtonPress
&& mouseEvent->button() == Qt::LeftButton && mouseEvent->button() == Qt::LeftButton
&& window()->windowState() != Qt::WindowMaximized) { && !_maximizedState) {
return startResize(edges); return startResize(edges);
} }
} }
@ -226,6 +282,11 @@ bool TitleWidgetQt::eventFilter(QObject *obj, QEvent *e) {
if (window() == static_cast<QWidget*>(obj)) { if (window() == static_cast<QWidget*>(obj)) {
restoreCursor(); restoreCursor();
} }
} else if (e->type() == QEvent::Move
|| e->type() == QEvent::Resize) {
if (window() == static_cast<QWidget*>(obj)) {
updateWindowExtents();
}
} }
return TitleWidget::eventFilter(obj, e); return TitleWidget::eventFilter(obj, e);
@ -240,6 +301,13 @@ void TitleWidgetQt::windowStateChanged(Qt::WindowState state) {
if (_maximizedState != maximized) { if (_maximizedState != maximized) {
_maximizedState = maximized; _maximizedState = maximized;
updateButtonsState(); updateButtonsState();
updateWindowExtents();
}
}
void TitleWidgetQt::visibleChanged(bool visible) {
if (visible) {
updateWindowExtents();
} }
} }
@ -273,26 +341,48 @@ void TitleWidgetQt::updateButtonsState() {
: nullptr); : nullptr);
} }
int TitleWidgetQt::getResizeArea(Qt::Edge edge) const {
if (!hasShadow()) {
return st::windowResizeArea;
}
if (edge == Qt::LeftEdge) {
return ShadowExtents().left();
} else if (edge == Qt::RightEdge) {
return ShadowExtents().right();
} else if (edge == Qt::TopEdge) {
return ShadowExtents().top();
} else if (edge == Qt::BottomEdge) {
return ShadowExtents().bottom();
}
return 0;
}
Qt::Edges TitleWidgetQt::edgesFromPos(const QPoint &pos) { Qt::Edges TitleWidgetQt::edgesFromPos(const QPoint &pos) {
if (pos.x() <= st::windowResizeArea) { if (pos.x() <= getResizeArea(Qt::LeftEdge)) {
if (pos.y() <= st::windowResizeArea) { if (pos.y() <= getResizeArea(Qt::TopEdge)) {
return Qt::LeftEdge | Qt::TopEdge; return Qt::LeftEdge | Qt::TopEdge;
} else if (pos.y() >= (window()->height() - st::windowResizeArea)) { } else if (pos.y()
>= (window()->height() - getResizeArea(Qt::BottomEdge))) {
return Qt::LeftEdge | Qt::BottomEdge; return Qt::LeftEdge | Qt::BottomEdge;
} }
return Qt::LeftEdge; return Qt::LeftEdge;
} else if (pos.x() >= (window()->width() - st::windowResizeArea)) { } else if (pos.x()
if (pos.y() <= st::windowResizeArea) { >= (window()->width() - getResizeArea(Qt::RightEdge))) {
if (pos.y() <= getResizeArea(Qt::TopEdge)) {
return Qt::RightEdge | Qt::TopEdge; return Qt::RightEdge | Qt::TopEdge;
} else if (pos.y() >= (window()->height() - st::windowResizeArea)) { } else if (pos.y()
>= (window()->height() - getResizeArea(Qt::BottomEdge))) {
return Qt::RightEdge | Qt::BottomEdge; return Qt::RightEdge | Qt::BottomEdge;
} }
return Qt::RightEdge; return Qt::RightEdge;
} else if (pos.y() <= st::windowResizeArea) { } else if (pos.y() <= getResizeArea(Qt::TopEdge)) {
return Qt::TopEdge; return Qt::TopEdge;
} else if (pos.y() >= (window()->height() - st::windowResizeArea)) { } else if (pos.y()
>= (window()->height() - getResizeArea(Qt::BottomEdge))) {
return Qt::BottomEdge; return Qt::BottomEdge;
} else { } else {
return 0; return 0;
@ -307,7 +397,7 @@ void TitleWidgetQt::restoreCursor() {
} }
void TitleWidgetQt::updateCursor(Qt::Edges edges) { void TitleWidgetQt::updateCursor(Qt::Edges edges) {
if (!edges || window()->windowState() == Qt::WindowMaximized) { if (!edges || _maximizedState) {
restoreCursor(); restoreCursor();
return; return;
} else if (!QGuiApplication::overrideCursor()) { } else if (!QGuiApplication::overrideCursor()) {

View file

@ -39,6 +39,8 @@ protected:
private: private:
void windowStateChanged(Qt::WindowState state = Qt::WindowNoState); void windowStateChanged(Qt::WindowState state = Qt::WindowNoState);
void visibleChanged(bool visible);
void updateWindowExtents();
void updateButtonsState(); void updateButtonsState();
void updateControlsPosition(); void updateControlsPosition();
void updateControlsPositionBySide( void updateControlsPositionBySide(
@ -46,6 +48,8 @@ private:
bool right); bool right);
void toggleFramelessWindow(bool enabled); void toggleFramelessWindow(bool enabled);
bool hasShadow() const;
int getResizeArea(Qt::Edge edge) const;
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();
@ -62,6 +66,7 @@ private:
bool _activeState = false; bool _activeState = false;
bool _windowWasFrameless = false; bool _windowWasFrameless = false;
bool _cursorOverriden = false; bool _cursorOverriden = false;
bool _extentsSet = false;
}; };

2
cmake

@ -1 +1 @@
Subproject commit 9b1ed3965b836131fe08b1090a8b5788a04066b8 Subproject commit fb7924a6ffeeaec17ed39203f49fb72dd9eff60f

View file

@ -68,6 +68,7 @@ parts:
parse-info: [usr/share/metainfo/kotatogramdesktop.appdata.xml] parse-info: [usr/share/metainfo/kotatogramdesktop.appdata.xml]
build-environment: build-environment:
- LD_LIBRARY_PATH: $SNAPCRAFT_STAGE/usr/lib - LD_LIBRARY_PATH: $SNAPCRAFT_STAGE/usr/lib
- tg_owt_DIR: $SNAPCRAFT_STAGE/tg_owt
build-packages: build-packages:
- python - python
- qtbase5-private-dev - qtbase5-private-dev
@ -104,7 +105,6 @@ parts:
- -DTDESKTOP_API_HASH=d524b414d21f4d37f08684c1df41ac9c - -DTDESKTOP_API_HASH=d524b414d21f4d37f08684c1df41ac9c
- -DDESKTOP_APP_USE_PACKAGED_LAZY=ON - -DDESKTOP_APP_USE_PACKAGED_LAZY=ON
- -DDESKTOP_APP_QTWAYLANDCLIENT_PRIVATE_HEADERS=$SNAPCRAFT_STAGE/usr/include/$SNAPCRAFT_ARCH_TRIPLET/qt5/QtWaylandClient/5.12.8 - -DDESKTOP_APP_QTWAYLANDCLIENT_PRIVATE_HEADERS=$SNAPCRAFT_STAGE/usr/include/$SNAPCRAFT_ARCH_TRIPLET/qt5/QtWaylandClient/5.12.8
- -DDESKTOP_APP_WEBRTC_LOCATION=$SNAPCRAFT_STAGE/webrtc/src
override-pull: | override-pull: |
snapcraftctl pull snapcraftctl pull
@ -119,14 +119,6 @@ parts:
- qtwayland - qtwayland
- webrtc - webrtc
patches:
source: https://github.com/desktop-app/patches.git
source-depth: 1
plugin: dump
organize:
"*": patches/
prime: [-./*]
telegram-patches: telegram-patches:
source: Telegram/Patches source: Telegram/Patches
plugin: dump plugin: dump
@ -134,14 +126,6 @@ parts:
"*": telegram_patches/ "*": telegram_patches/
prime: [-./*] prime: [-./*]
depot-tools:
source: https://chromium.googlesource.com/chromium/tools/depot_tools.git
source-depth: 1
plugin: dump
organize:
"*": depot_tools/
prime: [-./*]
desktop-qt5: desktop-qt5:
source: https://github.com/ubuntu/snapcraft-desktop-helpers.git source: https://github.com/ubuntu/snapcraft-desktop-helpers.git
source-subdir: qt source-subdir: qt
@ -360,79 +344,31 @@ parts:
qmake qmake
make -j$(nproc) make -j$(nproc)
make INSTALL_ROOT="$SNAPCRAFT_PART_INSTALL" install make INSTALL_ROOT="$SNAPCRAFT_PART_INSTALL" install
after:
- desktop-qt5
stage: [-./usr/lib] stage: [-./usr/lib]
prime: [-./*] prime: [-./*]
after:
- desktop-qt5
webrtc: webrtc:
plugin: nil source: https://github.com/ilya-fedin/tg_owt.git
source-depth: 1
source-branch: improve-packaged-build
plugin: cmake
build-packages: build-packages:
- curl - yasm
- python2 - libjpeg8-dev
- libopus-dev - libopus-dev
- libssl-dev - libssl-dev
stage-packages: stage-packages:
- libjpeg8
- libopus0 - libopus0
- libssl1.1 - libssl1.1
override-pull: |
export PATH="$SNAPCRAFT_STAGE/depot_tools:$PATH"
mkdir webrtc
cd webrtc
cp "$SNAPCRAFT_STAGE/patches/webrtc/.gclient" .
git clone --depth=1 https://github.com/open-webrtc-toolkit/owt-deps-webrtc src
gclient sync --no-history
applyPatch() {
cd "$SNAPCRAFT_PART_SRC/webrtc/$1"
git apply "$SNAPCRAFT_STAGE/patches/webrtc/$(basename $1).diff"
}
applyPatch src
applyPatch src/build
applyPatch src/third_party
applyPatch src/third_party/libsrtp
override-build: | override-build: |
export PATH="$SNAPCRAFT_STAGE/depot_tools:$PATH" cmake "$SNAPCRAFT_PART_SRC" -DCMAKE_BUILD_TYPE=Release
cmake --build . -- -j$(nproc)
cd webrtc/src cp -a . "$SNAPCRAFT_PART_INSTALL"
organize:
ArgumentsList=`echo \ "*": tg_owt/
target_os=\"linux\" \
treat_warnings_as_errors=false \
is_component_build=false \
is_debug=false \
is_clang=false \
proprietary_codecs=true \
use_custom_libcxx=false \
use_rtti=true \
use_gold=false \
use_sysroot=false \
linux_use_bundled_binutils=false \
enable_dsyms=true \
rtc_include_tests=false \
rtc_build_examples=false \
rtc_build_tools=false \
rtc_build_opus=false \
rtc_build_ssl=false \
rtc_ssl_root=\"/usr/include\" \
rtc_ssl_libs=[\"ssl\",\"crypto\"] \
rtc_builtin_ssl_root_certificates=true \
rtc_build_ffmpeg=false \
rtc_ffmpeg_root=\"$SNAPCRAFT_STAGE/usr/include\" \
rtc_ffmpeg_libs=[\"avcodec\",\"swscale\",\"swresample\",\"avutil\"] \
rtc_opus_root=\"/usr/include/opus\" \
rtc_enable_protobuf=false`
gn gen out/Release --args="$ArgumentsList"
ninja -C out/Release webrtc
cd ../..
cp -a webrtc "$SNAPCRAFT_PART_INSTALL"
after:
- depot-tools
- ffmpeg
- patches
prime: [-./*] prime: [-./*]
after:
- ffmpeg