mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +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_controller.cpp
|
||||
window/window_controller.h
|
||||
window/window_controls_layout.h
|
||||
window/window_filters_menu.cpp
|
||||
window/window_filters_menu.h
|
||||
window/window_history_hider.cpp
|
||||
|
|
|
@ -205,6 +205,8 @@ void Application::run() {
|
|||
return;
|
||||
}
|
||||
|
||||
Core::App().settings().setWindowControlsLayout(Platform::WindowControlsLayout());
|
||||
|
||||
_translator = std::make_unique<Lang::Translator>();
|
||||
QCoreApplication::instance()->installTranslator(_translator.get());
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "window/themes/window_themes_embedded.h"
|
||||
#include "window/window_controls_layout.h"
|
||||
|
||||
enum class SendFilesWay;
|
||||
enum class RectPart;
|
||||
|
@ -440,6 +441,18 @@ public:
|
|||
[[nodiscard]] rpl::producer<bool> systemDarkModeEnabledChanges() const {
|
||||
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]] float64 DefaultDialogsWidthRatio();
|
||||
|
@ -510,6 +523,7 @@ private:
|
|||
rpl::variable<bool> _nativeWindowFrame = false;
|
||||
rpl::variable<std::optional<bool>> _systemDarkMode = std::nullopt;
|
||||
rpl::variable<bool> _systemDarkModeEnabled = false;
|
||||
rpl::variable<Window::ControlsLayout> _windowControlsLayout;
|
||||
|
||||
bool _tabbedReplacedWithInfo = false; // per-window
|
||||
rpl::event_stream<bool> _tabbedReplacedWithInfoValue; // per-window
|
||||
|
|
|
@ -181,6 +181,12 @@ void DarkModeChanged() {
|
|||
Core::App().settings().setSystemDarkMode(Platform::IsDarkMode());
|
||||
});
|
||||
}
|
||||
|
||||
void DecorationLayoutChanged() {
|
||||
Core::Sandbox::Instance().customEnterFromEventLoop([] {
|
||||
Core::App().settings().setWindowControlsLayout(Platform::WindowControlsLayout());
|
||||
});
|
||||
}
|
||||
#endif // !TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||
|
||||
} // namespace
|
||||
|
@ -289,6 +295,10 @@ void start() {
|
|||
if (!gtk_check_version(3, 0, 0)) {
|
||||
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 {
|
||||
LOG(("Could not load gtk-3 or gtk-x11-2.0!"));
|
||||
}
|
||||
|
|
|
@ -580,6 +580,18 @@ bool StartWaylandResize(QWindow *window, Qt::Edges edges) {
|
|||
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
|
||||
|
||||
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 {
|
||||
|
|
|
@ -283,6 +283,17 @@ void IgnoreApplicationActivationRightNow() {
|
|||
objc_ignoreApplicationActivationRightNow();
|
||||
}
|
||||
|
||||
Window::ControlsLayout WindowControlsLayout() {
|
||||
Window::ControlsLayout controls;
|
||||
controls.left = {
|
||||
Window::Control::Close,
|
||||
Window::Control::Minimize,
|
||||
Window::Control::Maximize,
|
||||
};
|
||||
|
||||
return controls;
|
||||
}
|
||||
|
||||
} // namespace Platform
|
||||
|
||||
void psNewVersion() {
|
||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "window/window_controls_layout.h"
|
||||
|
||||
namespace Platform {
|
||||
|
||||
void start();
|
||||
|
@ -52,6 +54,7 @@ bool TrayIconSupported();
|
|||
QImage GetImageFromClipboard();
|
||||
bool StartSystemMove(QWindow *window);
|
||||
bool StartSystemResize(QWindow *window, Qt::Edges edges);
|
||||
Window::ControlsLayout WindowControlsLayout();
|
||||
|
||||
namespace ThirdParty {
|
||||
|
||||
|
|
|
@ -418,6 +418,17 @@ bool AutostartSupported() {
|
|||
return !IsWindowsStoreBuild();
|
||||
}
|
||||
|
||||
Window::ControlsLayout WindowControlsLayout() {
|
||||
Window::ControlsLayout controls;
|
||||
controls.right = {
|
||||
Window::Control::Minimize,
|
||||
Window::Control::Maximize,
|
||||
Window::Control::Close,
|
||||
};
|
||||
|
||||
return controls;
|
||||
}
|
||||
|
||||
} // namespace Platform
|
||||
|
||||
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 "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "core/core_settings.h"
|
||||
#include "core/application.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "base/call_delayed.h"
|
||||
|
||||
|
@ -54,6 +56,11 @@ TitleWidgetQt::TitleWidgetQt(QWidget *parent)
|
|||
});
|
||||
_close->setPointerCursor(false);
|
||||
|
||||
Core::App().settings().windowControlsLayoutChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
updateControlsPosition();
|
||||
}, lifetime());
|
||||
|
||||
QCoreApplication::instance()->installEventFilter(this);
|
||||
|
||||
_windowWasFrameless = (window()->windowFlags() & Qt::FramelessWindowHint) != 0;
|
||||
|
@ -106,10 +113,74 @@ void TitleWidgetQt::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
|
||||
void TitleWidgetQt::updateControlsPosition() {
|
||||
auto right = 0;
|
||||
_close->moveToRight(right, 0); right += _close->width();
|
||||
_maximizeRestore->moveToRight(right, 0); right += _maximizeRestore->width();
|
||||
_minimize->moveToRight(right, 0);
|
||||
const auto controlsLayout = Core::App().settings().windowControlsLayout();
|
||||
const auto controlsLeft = controlsLayout.left;
|
||||
const auto controlsRight = controlsLayout.right;
|
||||
|
||||
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) {
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "window/window_title.h"
|
||||
#include "window/window_controls_layout.h"
|
||||
#include "base/object_ptr.h"
|
||||
|
||||
namespace style {
|
||||
|
@ -40,6 +41,9 @@ private:
|
|||
void windowStateChanged(Qt::WindowState state = Qt::WindowNoState);
|
||||
void updateButtonsState();
|
||||
void updateControlsPosition();
|
||||
void updateControlsPositionBySide(
|
||||
const std::vector<Control> &controls,
|
||||
bool right);
|
||||
|
||||
void toggleFramelessWindow(bool enabled);
|
||||
Qt::Edges edgesFromPos(const QPoint &pos);
|
||||
|
|
Loading…
Add table
Reference in a new issue