mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-06 15:13:57 +02:00
Read decoration layout property from gtk
This commit is contained in:
parent
9e0b046213
commit
841908fe31
11 changed files with 218 additions and 4 deletions
|
@ -1089,6 +1089,7 @@ PRIVATE
|
||||||
window/window_connecting_widget.h
|
window/window_connecting_widget.h
|
||||||
window/window_controller.cpp
|
window/window_controller.cpp
|
||||||
window/window_controller.h
|
window/window_controller.h
|
||||||
|
window/window_controls_layout.h
|
||||||
window/window_filters_menu.cpp
|
window/window_filters_menu.cpp
|
||||||
window/window_filters_menu.h
|
window/window_filters_menu.h
|
||||||
window/window_history_hider.cpp
|
window/window_history_hider.cpp
|
||||||
|
|
|
@ -205,6 +205,8 @@ void Application::run() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Core::App().settings().setWindowControlsLayout(Platform::WindowControlsLayout());
|
||||||
|
|
||||||
_translator = std::make_unique<Lang::Translator>();
|
_translator = std::make_unique<Lang::Translator>();
|
||||||
QCoreApplication::instance()->installTranslator(_translator.get());
|
QCoreApplication::instance()->installTranslator(_translator.get());
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "window/themes/window_themes_embedded.h"
|
#include "window/themes/window_themes_embedded.h"
|
||||||
|
#include "window/window_controls_layout.h"
|
||||||
|
|
||||||
enum class SendFilesWay;
|
enum class SendFilesWay;
|
||||||
enum class RectPart;
|
enum class RectPart;
|
||||||
|
@ -440,6 +441,18 @@ public:
|
||||||
[[nodiscard]] rpl::producer<bool> systemDarkModeEnabledChanges() const {
|
[[nodiscard]] rpl::producer<bool> systemDarkModeEnabledChanges() const {
|
||||||
return _systemDarkModeEnabled.changes();
|
return _systemDarkModeEnabled.changes();
|
||||||
}
|
}
|
||||||
|
void setWindowControlsLayout(Window::ControlsLayout value) {
|
||||||
|
_windowControlsLayout = value;
|
||||||
|
}
|
||||||
|
[[nodiscard]] Window::ControlsLayout windowControlsLayout() const {
|
||||||
|
return _windowControlsLayout.current();
|
||||||
|
}
|
||||||
|
[[nodiscard]] rpl::producer<Window::ControlsLayout> windowControlsLayoutValue() const {
|
||||||
|
return _windowControlsLayout.value();
|
||||||
|
}
|
||||||
|
[[nodiscard]] rpl::producer<Window::ControlsLayout> windowControlsLayoutChanges() const {
|
||||||
|
return _windowControlsLayout.changes();
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] static bool ThirdColumnByDefault();
|
[[nodiscard]] static bool ThirdColumnByDefault();
|
||||||
[[nodiscard]] float64 DefaultDialogsWidthRatio();
|
[[nodiscard]] float64 DefaultDialogsWidthRatio();
|
||||||
|
@ -510,6 +523,7 @@ private:
|
||||||
rpl::variable<bool> _nativeWindowFrame = false;
|
rpl::variable<bool> _nativeWindowFrame = false;
|
||||||
rpl::variable<std::optional<bool>> _systemDarkMode = std::nullopt;
|
rpl::variable<std::optional<bool>> _systemDarkMode = std::nullopt;
|
||||||
rpl::variable<bool> _systemDarkModeEnabled = false;
|
rpl::variable<bool> _systemDarkModeEnabled = false;
|
||||||
|
rpl::variable<Window::ControlsLayout> _windowControlsLayout;
|
||||||
|
|
||||||
bool _tabbedReplacedWithInfo = false; // per-window
|
bool _tabbedReplacedWithInfo = false; // per-window
|
||||||
rpl::event_stream<bool> _tabbedReplacedWithInfoValue; // per-window
|
rpl::event_stream<bool> _tabbedReplacedWithInfoValue; // per-window
|
||||||
|
|
|
@ -181,6 +181,12 @@ void DarkModeChanged() {
|
||||||
Core::App().settings().setSystemDarkMode(Platform::IsDarkMode());
|
Core::App().settings().setSystemDarkMode(Platform::IsDarkMode());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DecorationLayoutChanged() {
|
||||||
|
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
||||||
|
Core::App().settings().setWindowControlsLayout(Platform::WindowControlsLayout());
|
||||||
|
});
|
||||||
|
}
|
||||||
#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION
|
#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -289,6 +295,10 @@ void start() {
|
||||||
if (!gtk_check_version(3, 0, 0)) {
|
if (!gtk_check_version(3, 0, 0)) {
|
||||||
g_signal_connect(settings, "notify::gtk-application-prefer-dark-theme", G_CALLBACK(DarkModeChanged), nullptr);
|
g_signal_connect(settings, "notify::gtk-application-prefer-dark-theme", G_CALLBACK(DarkModeChanged), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gtk_check_version(3, 12, 0)) {
|
||||||
|
g_signal_connect(settings, "notify::gtk-decoration-layout", G_CALLBACK(DecorationLayoutChanged), nullptr);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG(("Could not load gtk-3 or gtk-x11-2.0!"));
|
LOG(("Could not load gtk-3 or gtk-x11-2.0!"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -580,6 +580,18 @@ bool StartWaylandResize(QWindow *window, Qt::Edges edges) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window::Control GtkKeywordToWindowControl(const QString &keyword) {
|
||||||
|
if (keyword == qstr("minimize")) {
|
||||||
|
return Window::Control::Minimize;
|
||||||
|
} else if (keyword == qstr("maximize")) {
|
||||||
|
return Window::Control::Maximize;
|
||||||
|
} else if (keyword == qstr("close")) {
|
||||||
|
return Window::Control::Close;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Window::Control::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void SetApplicationIcon(const QIcon &icon) {
|
void SetApplicationIcon(const QIcon &icon) {
|
||||||
|
@ -939,6 +951,57 @@ bool StartSystemResize(QWindow *window, Qt::Edges edges) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window::ControlsLayout WindowControlsLayout() {
|
||||||
|
#ifndef TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||||
|
if (Libs::GtkSettingSupported()
|
||||||
|
&& Libs::GtkLoaded()
|
||||||
|
&& Libs::gtk_check_version != nullptr
|
||||||
|
&& !Libs::gtk_check_version(3, 12, 0)) {
|
||||||
|
const auto decorationLayout = Libs::GtkSetting("gtk-decoration-layout").split(':');
|
||||||
|
|
||||||
|
std::vector<Window::Control> controlsLeft;
|
||||||
|
ranges::transform(
|
||||||
|
decorationLayout[0].split(','),
|
||||||
|
ranges::back_inserter(controlsLeft),
|
||||||
|
GtkKeywordToWindowControl
|
||||||
|
);
|
||||||
|
|
||||||
|
std::vector<Window::Control> controlsRight;
|
||||||
|
if (decorationLayout.size() > 1) {
|
||||||
|
ranges::transform(
|
||||||
|
decorationLayout[1].split(','),
|
||||||
|
ranges::back_inserter(controlsRight),
|
||||||
|
GtkKeywordToWindowControl
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Window::ControlsLayout controls;
|
||||||
|
controls.left = controlsLeft;
|
||||||
|
controls.right = controlsRight;
|
||||||
|
|
||||||
|
return controls;
|
||||||
|
}
|
||||||
|
#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||||
|
|
||||||
|
Window::ControlsLayout controls;
|
||||||
|
|
||||||
|
if (DesktopEnvironment::IsUnity()) {
|
||||||
|
controls.left = {
|
||||||
|
Window::Control::Close,
|
||||||
|
Window::Control::Minimize,
|
||||||
|
Window::Control::Maximize,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
controls.right = {
|
||||||
|
Window::Control::Minimize,
|
||||||
|
Window::Control::Maximize,
|
||||||
|
Window::Control::Close,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return controls;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Platform
|
} // namespace Platform
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -283,6 +283,17 @@ void IgnoreApplicationActivationRightNow() {
|
||||||
objc_ignoreApplicationActivationRightNow();
|
objc_ignoreApplicationActivationRightNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window::ControlsLayout WindowControlsLayout() {
|
||||||
|
Window::ControlsLayout controls;
|
||||||
|
controls.left = {
|
||||||
|
Window::Control::Close,
|
||||||
|
Window::Control::Minimize,
|
||||||
|
Window::Control::Maximize,
|
||||||
|
};
|
||||||
|
|
||||||
|
return controls;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Platform
|
} // namespace Platform
|
||||||
|
|
||||||
void psNewVersion() {
|
void psNewVersion() {
|
||||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "window/window_controls_layout.h"
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
|
@ -52,6 +54,7 @@ bool TrayIconSupported();
|
||||||
QImage GetImageFromClipboard();
|
QImage GetImageFromClipboard();
|
||||||
bool StartSystemMove(QWindow *window);
|
bool StartSystemMove(QWindow *window);
|
||||||
bool StartSystemResize(QWindow *window, Qt::Edges edges);
|
bool StartSystemResize(QWindow *window, Qt::Edges edges);
|
||||||
|
Window::ControlsLayout WindowControlsLayout();
|
||||||
|
|
||||||
namespace ThirdParty {
|
namespace ThirdParty {
|
||||||
|
|
||||||
|
|
|
@ -418,6 +418,17 @@ bool AutostartSupported() {
|
||||||
return !IsWindowsStoreBuild();
|
return !IsWindowsStoreBuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window::ControlsLayout WindowControlsLayout() {
|
||||||
|
Window::ControlsLayout controls;
|
||||||
|
controls.right = {
|
||||||
|
Window::Control::Minimize,
|
||||||
|
Window::Control::Maximize,
|
||||||
|
Window::Control::Close,
|
||||||
|
};
|
||||||
|
|
||||||
|
return controls;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Platform
|
} // namespace Platform
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
24
Telegram/SourceFiles/window/window_controls_layout.h
Normal file
24
Telegram/SourceFiles/window/window_controls_layout.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Window {
|
||||||
|
|
||||||
|
enum class Control {
|
||||||
|
Unknown,
|
||||||
|
Minimize,
|
||||||
|
Maximize,
|
||||||
|
Close,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ControlsLayout {
|
||||||
|
std::vector<Control> left;
|
||||||
|
std::vector<Control> right;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Window
|
|
@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "platform/platform_specific.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 "core/core_settings.h"
|
||||||
|
#include "core/application.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
#include "base/call_delayed.h"
|
#include "base/call_delayed.h"
|
||||||
|
|
||||||
|
@ -54,6 +56,11 @@ TitleWidgetQt::TitleWidgetQt(QWidget *parent)
|
||||||
});
|
});
|
||||||
_close->setPointerCursor(false);
|
_close->setPointerCursor(false);
|
||||||
|
|
||||||
|
Core::App().settings().windowControlsLayoutChanges(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
updateControlsPosition();
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
QCoreApplication::instance()->installEventFilter(this);
|
QCoreApplication::instance()->installEventFilter(this);
|
||||||
|
|
||||||
_windowWasFrameless = (window()->windowFlags() & Qt::FramelessWindowHint) != 0;
|
_windowWasFrameless = (window()->windowFlags() & Qt::FramelessWindowHint) != 0;
|
||||||
|
@ -106,10 +113,74 @@ void TitleWidgetQt::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TitleWidgetQt::updateControlsPosition() {
|
void TitleWidgetQt::updateControlsPosition() {
|
||||||
auto right = 0;
|
const auto controlsLayout = Core::App().settings().windowControlsLayout();
|
||||||
_close->moveToRight(right, 0); right += _close->width();
|
const auto controlsLeft = controlsLayout.left;
|
||||||
_maximizeRestore->moveToRight(right, 0); right += _maximizeRestore->width();
|
const auto controlsRight = controlsLayout.right;
|
||||||
_minimize->moveToRight(right, 0);
|
|
||||||
|
if (ranges::contains(controlsLeft, Control::Minimize)
|
||||||
|
|| ranges::contains(controlsRight, Control::Minimize)) {
|
||||||
|
_minimize->show();
|
||||||
|
} else {
|
||||||
|
_minimize->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ranges::contains(controlsLeft, Control::Maximize)
|
||||||
|
|| ranges::contains(controlsRight, Control::Maximize)) {
|
||||||
|
_maximizeRestore->show();
|
||||||
|
} else {
|
||||||
|
_maximizeRestore->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ranges::contains(controlsLeft, Control::Close)
|
||||||
|
|| ranges::contains(controlsRight, Control::Close)) {
|
||||||
|
_close->show();
|
||||||
|
} else {
|
||||||
|
_close->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateControlsPositionBySide(controlsLeft, false);
|
||||||
|
updateControlsPositionBySide(controlsRight, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TitleWidgetQt::updateControlsPositionBySide(
|
||||||
|
const std::vector<Control> &controls,
|
||||||
|
bool right) {
|
||||||
|
const auto preparedControls = right
|
||||||
|
? (ranges::view::reverse(controls) | ranges::to_vector)
|
||||||
|
: controls;
|
||||||
|
|
||||||
|
auto position = 0;
|
||||||
|
for (const auto &control : preparedControls) {
|
||||||
|
switch (control) {
|
||||||
|
case Control::Minimize:
|
||||||
|
if (right) {
|
||||||
|
_minimize->moveToRight(position, 0);
|
||||||
|
} else {
|
||||||
|
_minimize->moveToLeft(position, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
position += _minimize->width();
|
||||||
|
break;
|
||||||
|
case Control::Maximize:
|
||||||
|
if (right) {
|
||||||
|
_maximizeRestore->moveToRight(position, 0);
|
||||||
|
} else {
|
||||||
|
_maximizeRestore->moveToLeft(position, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
position += _maximizeRestore->width();
|
||||||
|
break;
|
||||||
|
case Control::Close:
|
||||||
|
if (right) {
|
||||||
|
_close->moveToRight(position, 0);
|
||||||
|
} else {
|
||||||
|
_close->moveToLeft(position, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
position += _close->width();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TitleWidgetQt::resizeEvent(QResizeEvent *e) {
|
void TitleWidgetQt::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "window/window_title.h"
|
#include "window/window_title.h"
|
||||||
|
#include "window/window_controls_layout.h"
|
||||||
#include "base/object_ptr.h"
|
#include "base/object_ptr.h"
|
||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
|
@ -40,6 +41,9 @@ private:
|
||||||
void windowStateChanged(Qt::WindowState state = Qt::WindowNoState);
|
void windowStateChanged(Qt::WindowState state = Qt::WindowNoState);
|
||||||
void updateButtonsState();
|
void updateButtonsState();
|
||||||
void updateControlsPosition();
|
void updateControlsPosition();
|
||||||
|
void updateControlsPositionBySide(
|
||||||
|
const std::vector<Control> &controls,
|
||||||
|
bool right);
|
||||||
|
|
||||||
void toggleFramelessWindow(bool enabled);
|
void toggleFramelessWindow(bool enabled);
|
||||||
Qt::Edges edgesFromPos(const QPoint &pos);
|
Qt::Edges edgesFromPos(const QPoint &pos);
|
||||||
|
|
Loading…
Add table
Reference in a new issue