Move TitleControlsLayout from ui_platform_utility to ui_platform_window_title

This commit is contained in:
Ilya Fedin 2023-07-19 14:09:06 +04:00 committed by John Preston
parent 6419b54383
commit 19d044a212
12 changed files with 238 additions and 222 deletions

View file

@ -112,6 +112,8 @@ PRIVATE
ui/platform/linux/ui_linux_wayland_integration.h
ui/platform/linux/ui_window_linux.cpp
ui/platform/linux/ui_window_linux.h
ui/platform/linux/ui_window_title_linux.cpp
ui/platform/linux/ui_window_title_linux.h
ui/platform/linux/ui_utility_linux.cpp
ui/platform/linux/ui_utility_linux.h
ui/platform/mac/ui_window_mac.h
@ -134,7 +136,6 @@ PRIVATE
ui/platform/ui_platform_window_title.h
ui/platform/ui_platform_window.cpp
ui/platform/ui_platform_window.h
ui/platform/ui_platform_utility.cpp
ui/platform/ui_platform_utility.h
ui/style/style_core.cpp
ui/style/style_core.h

View file

@ -7,15 +7,12 @@
#include "ui/platform/linux/ui_utility_linux.h"
#include "base/platform/base_platform_info.h"
#include "base/platform/linux/base_linux_glibmm_helper.h"
#include "base/platform/linux/base_linux_xdp_utilities.h"
#include "base/call_delayed.h"
#include "base/const_string.h"
#include "ui/platform/linux/ui_linux_wayland_integration.h"
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
#include "base/platform/linux/base_linux_xcb_utilities.h"
#include "base/platform/linux/base_linux_xsettings.h"
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
#include <QtCore/QPoint>
@ -399,41 +396,6 @@ void ShowXCBWindowMenu(not_null<QWidget*> widget, const QPoint &point) {
}
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
TitleControls::Control GtkKeywordToTitleControl(const QString &keyword) {
if (keyword == qstr("minimize")) {
return TitleControls::Control::Minimize;
} else if (keyword == qstr("maximize")) {
return TitleControls::Control::Maximize;
} else if (keyword == qstr("close")) {
return TitleControls::Control::Close;
}
return TitleControls::Control::Unknown;
}
TitleControls::Layout GtkKeywordsToTitleControlsLayout(const QString &keywords) {
const auto splitted = keywords.split(':');
std::vector<TitleControls::Control> controlsLeft;
ranges::transform(
splitted[0].split(','),
ranges::back_inserter(controlsLeft),
GtkKeywordToTitleControl);
std::vector<TitleControls::Control> controlsRight;
if (splitted.size() > 1) {
ranges::transform(
splitted[1].split(','),
ranges::back_inserter(controlsRight),
GtkKeywordToTitleControl);
}
return TitleControls::Layout{
.left = controlsLeft,
.right = controlsRight
};
}
} // namespace
bool IsApplicationActive() {
@ -581,94 +543,5 @@ void GotApplicationActivateEvent() {
PendingDeactivateEvent = false;
}
namespace internal {
TitleControls::Layout TitleControlsLayout() {
[[maybe_unused]] static const auto Inited = [] {
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
using base::Platform::XCB::XSettings;
if (const auto xSettings = XSettings::Instance()) {
xSettings->registerCallbackForProperty("Gtk/DecorationLayout", [](
xcb_connection_t *,
const QByteArray &,
const QVariant &,
void *) {
NotifyTitleControlsLayoutChanged();
}, nullptr);
}
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
using XDPSettingWatcher = base::Platform::XDP::SettingWatcher;
static const XDPSettingWatcher settingWatcher(
[=](
const Glib::ustring &group,
const Glib::ustring &key,
const Glib::VariantBase &value) {
if (group == "org.gnome.desktop.wm.preferences"
&& key == "button-layout") {
NotifyTitleControlsLayoutChanged();
}
});
return true;
}();
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
const auto xSettingsResult = []() -> std::optional<TitleControls::Layout> {
using base::Platform::XCB::XSettings;
const auto xSettings = XSettings::Instance();
if (!xSettings) {
return std::nullopt;
}
const auto decorationLayout = xSettings->setting("Gtk/DecorationLayout");
if (!decorationLayout.isValid()) {
return std::nullopt;
}
return GtkKeywordsToTitleControlsLayout(decorationLayout.toString());
}();
if (xSettingsResult.has_value()) {
return *xSettingsResult;
}
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
const auto portalResult = []() -> std::optional<TitleControls::Layout> {
try {
using namespace base::Platform::XDP;
const auto decorationLayout = ReadSetting(
"org.gnome.desktop.wm.preferences",
"button-layout");
if (!decorationLayout.has_value()) {
return std::nullopt;
}
return GtkKeywordsToTitleControlsLayout(
QString::fromStdString(
base::Platform::GlibVariantCast<Glib::ustring>(
*decorationLayout)));
} catch (...) {
}
return std::nullopt;
}();
if (portalResult.has_value()) {
return *portalResult;
}
return TitleControls::Layout{
.right = {
TitleControls::Control::Minimize,
TitleControls::Control::Maximize,
TitleControls::Control::Close,
}
};
}
} // namespace internal
} // namespace Platform
} // namespace Ui

View file

@ -0,0 +1,146 @@
// This file is part of Desktop App Toolkit,
// a set of libraries for developing nice desktop applications.
//
// For license and copyright information please follow this link:
// https://github.com/desktop-app/legal/blob/master/LEGAL
//
#include "ui/platform/linux/ui_window_title_linux.h"
#include "base/platform/linux/base_linux_glibmm_helper.h"
#include "base/platform/linux/base_linux_xdp_utilities.h"
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
#include "base/platform/linux/base_linux_xsettings.h"
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
namespace Ui {
namespace Platform {
namespace internal {
namespace {
TitleControls::Control GtkKeywordToTitleControl(const QString &keyword) {
if (keyword == qstr("minimize")) {
return TitleControls::Control::Minimize;
} else if (keyword == qstr("maximize")) {
return TitleControls::Control::Maximize;
} else if (keyword == qstr("close")) {
return TitleControls::Control::Close;
}
return TitleControls::Control::Unknown;
}
TitleControls::Layout GtkKeywordsToTitleControlsLayout(const QString &keywords) {
const auto splitted = keywords.split(':');
std::vector<TitleControls::Control> controlsLeft;
ranges::transform(
splitted[0].split(','),
ranges::back_inserter(controlsLeft),
GtkKeywordToTitleControl);
std::vector<TitleControls::Control> controlsRight;
if (splitted.size() > 1) {
ranges::transform(
splitted[1].split(','),
ranges::back_inserter(controlsRight),
GtkKeywordToTitleControl);
}
return TitleControls::Layout{
.left = controlsLeft,
.right = controlsRight,
};
}
} // namespace
TitleControls::Layout TitleControlsLayout() {
[[maybe_unused]] static const auto Inited = [] {
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
using base::Platform::XCB::XSettings;
if (const auto xSettings = XSettings::Instance()) {
xSettings->registerCallbackForProperty("Gtk/DecorationLayout", [](
xcb_connection_t *,
const QByteArray &,
const QVariant &,
void *) {
NotifyTitleControlsLayoutChanged();
}, nullptr);
}
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
using XDPSettingWatcher = base::Platform::XDP::SettingWatcher;
static const XDPSettingWatcher settingWatcher(
[=](
const Glib::ustring &group,
const Glib::ustring &key,
const Glib::VariantBase &value) {
if (group == "org.gnome.desktop.wm.preferences"
&& key == "button-layout") {
NotifyTitleControlsLayoutChanged();
}
});
return true;
}();
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
const auto xSettingsResult = []() -> std::optional<TitleControls::Layout> {
using base::Platform::XCB::XSettings;
const auto xSettings = XSettings::Instance();
if (!xSettings) {
return std::nullopt;
}
const auto decorationLayout = xSettings->setting("Gtk/DecorationLayout");
if (!decorationLayout.isValid()) {
return std::nullopt;
}
return GtkKeywordsToTitleControlsLayout(decorationLayout.toString());
}();
if (xSettingsResult.has_value()) {
return *xSettingsResult;
}
#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
const auto portalResult = []() -> std::optional<TitleControls::Layout> {
try {
using namespace base::Platform::XDP;
const auto decorationLayout = ReadSetting(
"org.gnome.desktop.wm.preferences",
"button-layout");
if (!decorationLayout.has_value()) {
return std::nullopt;
}
return GtkKeywordsToTitleControlsLayout(
QString::fromStdString(
base::Platform::GlibVariantCast<Glib::ustring>(
*decorationLayout)));
} catch (...) {
}
return std::nullopt;
}();
if (portalResult.has_value()) {
return *portalResult;
}
return TitleControls::Layout{
.right = {
TitleControls::Control::Minimize,
TitleControls::Control::Maximize,
TitleControls::Control::Close,
}
};
}
} // namespace internal
} // namespace Platform
} // namespace Ui

View file

@ -0,0 +1,9 @@
// This file is part of Desktop App Toolkit,
// a set of libraries for developing nice desktop applications.
//
// For license and copyright information please follow this link:
// https://github.com/desktop-app/legal/blob/master/LEGAL
//
#pragma once
#include "ui/platform/ui_platform_window_title.h"

View file

@ -157,18 +157,5 @@ bool SkipApplicationDeactivateEvent() {
void GotApplicationActivateEvent() {
}
namespace internal {
TitleControls::Layout TitleControlsLayout() {
return TitleControls::Layout{
.left = {
TitleControls::Control::Close,
TitleControls::Control::Minimize,
TitleControls::Control::Maximize,
}
};
}
} // namespace internal
} // namespace Platform
} // namespace Ui

View file

@ -20,6 +20,19 @@
namespace Ui {
namespace Platform {
namespace internal {
TitleControls::Layout TitleControlsLayout() {
return TitleControls::Layout{
.left = {
TitleControls::Control::Close,
TitleControls::Control::Minimize,
TitleControls::Control::Maximize,
}
};
}
} // namespace internal
TitleWidget::TitleWidget(not_null<RpWidget*> parent, int height)
: RpWidget(parent)

View file

@ -1,42 +0,0 @@
// This file is part of Desktop App Toolkit,
// a set of libraries for developing nice desktop applications.
//
// For license and copyright information please follow this link:
// https://github.com/desktop-app/legal/blob/master/LEGAL
//
#include "ui/platform/ui_platform_utility.h"
namespace Ui {
namespace Platform {
namespace internal {
namespace {
auto &CachedTitleControlsLayout() {
using Layout = TitleControls::Layout;
static rpl::variable<Layout> Result = TitleControlsLayout();
return Result;
};
} // namespace
void NotifyTitleControlsLayoutChanged(
const std::optional<TitleControls::Layout> &layout) {
CachedTitleControlsLayout() = layout ? *layout : TitleControlsLayout();
}
} // namespace internal
TitleControls::Layout TitleControlsLayout() {
return internal::CachedTitleControlsLayout().current();
}
rpl::producer<TitleControls::Layout> TitleControlsLayoutValue() {
return internal::CachedTitleControlsLayout().value();
}
rpl::producer<TitleControls::Layout> TitleControlsLayoutChanged() {
return internal::CachedTitleControlsLayout().changes();
}
} // namespace Platform
} // namespace Ui

View file

@ -6,8 +6,6 @@
//
#pragma once
#include "ui/platform/ui_platform_window_title.h"
class QPoint;
class QPainter;
class QPaintEvent;
@ -17,14 +15,6 @@ class PopupMenu;
} // namespace Ui
namespace Ui::Platform {
namespace internal {
// Actual requestor, cached by the public interface
[[nodiscard]] TitleControls::Layout TitleControlsLayout();
void NotifyTitleControlsLayoutChanged(
const std::optional<TitleControls::Layout> &layout = std::nullopt);
} // namespace internal
[[nodiscard]] bool IsApplicationActive();
@ -53,21 +43,6 @@ 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();
[[nodiscard]] rpl::producer<TitleControls::Layout> TitleControlsLayoutChanged();
[[nodiscard]] bool TitleControlsOnLeft(
const TitleControls::Layout &layout = TitleControlsLayout()) {
if (ranges::contains(layout.left, TitleControl::Close)) {
return true;
} else if (ranges::contains(layout.right, TitleControl::Close)) {
return false;
} else if (layout.left.size() > layout.right.size()) {
return true;
}
return false;
}
void FixPopupMenuNativeEmojiPopup(not_null<PopupMenu*> menu);
// Workaround for a Qt/Wayland bug that hides the parent popup when

View file

@ -441,6 +441,36 @@ void TitleControls::updateButtonsState() {
_buttons->updateState(_activeState, _maximizedState, *_st);
}
namespace internal {
namespace {
auto &CachedTitleControlsLayout() {
using Layout = TitleControls::Layout;
static rpl::variable<Layout> Result = TitleControlsLayout();
return Result;
};
} // namespace
void NotifyTitleControlsLayoutChanged(
const std::optional<TitleControls::Layout> &layout) {
CachedTitleControlsLayout() = layout ? *layout : TitleControlsLayout();
}
} // namespace internal
TitleControls::Layout TitleControlsLayout() {
return internal::CachedTitleControlsLayout().current();
}
rpl::producer<TitleControls::Layout> TitleControlsLayoutValue() {
return internal::CachedTitleControlsLayout().value();
}
rpl::producer<TitleControls::Layout> TitleControlsLayoutChanged() {
return internal::CachedTitleControlsLayout().changes();
}
DefaultTitleWidget::DefaultTitleWidget(not_null<RpWidget*> parent)
: RpWidget(parent)
, _controls(this, st::defaultWindowTitle)

View file

@ -154,6 +154,30 @@ private:
};
namespace internal {
// Actual requestor, cached by the public interface
[[nodiscard]] TitleControls::Layout TitleControlsLayout();
void NotifyTitleControlsLayoutChanged(
const std::optional<TitleControls::Layout> &layout = std::nullopt);
} // namespace internal
[[nodiscard]] TitleControls::Layout TitleControlsLayout();
[[nodiscard]] rpl::producer<TitleControls::Layout> TitleControlsLayoutValue();
[[nodiscard]] rpl::producer<TitleControls::Layout> TitleControlsLayoutChanged();
[[nodiscard]] bool TitleControlsOnLeft(
const TitleControls::Layout &layout = TitleControlsLayout()) {
if (ranges::contains(layout.left, TitleControl::Close)) {
return true;
} else if (ranges::contains(layout.right, TitleControl::Close)) {
return false;
} else if (layout.left.size() > layout.right.size()) {
return true;
}
return false;
}
class DefaultTitleWidget : public RpWidget {
public:
explicit DefaultTitleWidget(not_null<RpWidget*> parent);

View file

@ -134,20 +134,6 @@ void ShowWindowMenu(not_null<QWidget*> widget, const QPoint &point) {
MAKELPARAM(p.x, p.y));
}
namespace internal {
TitleControls::Layout TitleControlsLayout() {
return TitleControls::Layout{
.right = {
TitleControls::Control::Minimize,
TitleControls::Control::Maximize,
TitleControls::Control::Close,
}
};
}
} // namespace internal
void FixPopupMenuNativeEmojiPopup(not_null<PopupMenu*> menu) {
// Windows native emoji selector, that can be called by Win+. shortcut,
// is behaving strangely within an input field in a popup menu.

View file

@ -44,6 +44,20 @@ HRESULT(__stdcall *GetScaleFactorForMonitor)(
} // namespace
namespace internal {
TitleControls::Layout TitleControlsLayout() {
return TitleControls::Layout{
.right = {
TitleControls::Control::Minimize,
TitleControls::Control::Maximize,
TitleControls::Control::Close,
}
};
}
} // namespace internal
struct TitleWidget::PaddingHelper {
explicit PaddingHelper(QWidget *parent) : controlsParent(parent) {
}