mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-04-11 04:01:18 +00:00
Paint native title instead of using custom.
This commit is contained in:
parent
4e1b94d37d
commit
7fdeab829f
@ -65,6 +65,7 @@ public slots:
|
|||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *obj, QEvent *evt) override;
|
bool eventFilter(QObject *obj, QEvent *evt) override;
|
||||||
|
|
||||||
|
void handleActiveChangedHook() override;
|
||||||
void stateChangedHook(Qt::WindowState state) override;
|
void stateChangedHook(Qt::WindowState state) override;
|
||||||
void initHook() override;
|
void initHook() override;
|
||||||
void updateWindowIcon() override;
|
void updateWindowIcon() override;
|
||||||
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||||||
#include "history/history_inner_widget.h"
|
#include "history/history_inner_widget.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "window/notifications_manager_default.h"
|
#include "window/notifications_manager_default.h"
|
||||||
|
#include "window/themes/window_theme.h"
|
||||||
#include "platform/platform_notifications_manager.h"
|
#include "platform/platform_notifications_manager.h"
|
||||||
#include "boxes/peer_list_controllers.h"
|
#include "boxes/peer_list_controllers.h"
|
||||||
#include "boxes/about_box.h"
|
#include "boxes/about_box.h"
|
||||||
@ -44,6 +45,17 @@ namespace {
|
|||||||
// fullscreen mode, after that we'll hide the window no matter what.
|
// fullscreen mode, after that we'll hide the window no matter what.
|
||||||
constexpr auto kHideAfterFullscreenTimeoutMs = 3000;
|
constexpr auto kHideAfterFullscreenTimeoutMs = 3000;
|
||||||
|
|
||||||
|
id FindClassInSubviews(NSView *parent, NSString *className) {
|
||||||
|
for (NSView *child in [parent subviews]) {
|
||||||
|
if ([child isKindOfClass:NSClassFromString(className)]) {
|
||||||
|
return child;
|
||||||
|
} else if (id inchild = FindClassInSubviews(child, className)) {
|
||||||
|
return inchild;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@interface MainWindowObserver : NSObject {
|
@interface MainWindowObserver : NSObject {
|
||||||
@ -65,7 +77,10 @@ class MainWindow::Private {
|
|||||||
public:
|
public:
|
||||||
Private(MainWindow *window);
|
Private(MainWindow *window);
|
||||||
|
|
||||||
|
void setNativeWindow(NSWindow *window, NSView *view);
|
||||||
void setWindowBadge(const QString &str);
|
void setWindowBadge(const QString &str);
|
||||||
|
void setWindowTitle(const QString &str);
|
||||||
|
void updateNativeTitle();
|
||||||
|
|
||||||
void enableShadow(WId winId);
|
void enableShadow(WId winId);
|
||||||
|
|
||||||
@ -74,16 +89,29 @@ public:
|
|||||||
void willEnterFullScreen();
|
void willEnterFullScreen();
|
||||||
void willExitFullScreen();
|
void willExitFullScreen();
|
||||||
|
|
||||||
void initCustomTitle(NSWindow *window, NSView *view);
|
|
||||||
|
|
||||||
bool clipboardHasText();
|
bool clipboardHasText();
|
||||||
|
|
||||||
~Private();
|
~Private();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void initCustomTitle();
|
||||||
|
void refreshWeakTitleReferences();
|
||||||
|
|
||||||
MainWindow *_public;
|
MainWindow *_public;
|
||||||
friend class MainWindow;
|
friend class MainWindow;
|
||||||
|
|
||||||
|
#ifdef OS_MAC_OLD
|
||||||
|
NSWindow *_nativeWindow = nil;
|
||||||
|
NSView *_nativeView = nil;
|
||||||
|
#else // OS_MAC_OLD
|
||||||
|
NSWindow * __weak _nativeWindow = nil;
|
||||||
|
NSView * __weak _nativeView = nil;
|
||||||
|
id __weak _nativeTitleWrapWeak = nil;
|
||||||
|
id __weak _nativeTitleWeak = nil;
|
||||||
|
#endif // !OS_MAC_OLD
|
||||||
|
bool _useNativeTitle = false;
|
||||||
|
bool _inFullScreen = false;
|
||||||
|
|
||||||
MainWindowObserver *_observer;
|
MainWindowObserver *_observer;
|
||||||
NSPasteboard *_generalPasteboard = nullptr;
|
NSPasteboard *_generalPasteboard = nullptr;
|
||||||
int _generalPasteboardChangeCount = -1;
|
int _generalPasteboardChangeCount = -1;
|
||||||
@ -160,16 +188,107 @@ void MainWindow::Private::setWindowBadge(const QString &str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::Private::initCustomTitle(NSWindow *window, NSView *view) {
|
void MainWindow::Private::setWindowTitle(const QString &str) {
|
||||||
[window setStyleMask:[window styleMask] | NSFullSizeContentViewWindowMask];
|
_public->setWindowTitle(str);
|
||||||
[window setTitlebarAppearsTransparent:YES];
|
updateNativeTitle();
|
||||||
auto inner = [window contentLayoutRect];
|
}
|
||||||
auto full = [view frame];
|
|
||||||
_public->_customTitleHeight = qMax(qRound(full.size.height - inner.size.height), 0);
|
void MainWindow::Private::setNativeWindow(NSWindow *window, NSView *view) {
|
||||||
|
_nativeWindow = window;
|
||||||
|
_nativeView = view;
|
||||||
|
initCustomTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::Private::initCustomTitle() {
|
||||||
|
#ifndef OS_MAC_OLD
|
||||||
|
if (![_nativeWindow respondsToSelector:@selector(contentLayoutRect)]
|
||||||
|
|| ![_nativeWindow respondsToSelector:@selector(setTitlebarAppearsTransparent:)]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
[_nativeWindow setTitlebarAppearsTransparent:YES];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:_observer selector:@selector(windowWillEnterFullScreen:) name:NSWindowWillEnterFullScreenNotification object:_nativeWindow];
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:_observer selector:@selector(windowWillExitFullScreen:) name:NSWindowWillExitFullScreenNotification object:_nativeWindow];
|
||||||
|
|
||||||
|
// Qt has bug with layer-backed widgets containing QOpenGLWidgets.
|
||||||
|
// See https://bugreports.qt.io/browse/QTBUG-64494
|
||||||
|
// Emulate custom title instead (code below).
|
||||||
|
// [window setStyleMask:[window styleMask] | NSFullSizeContentViewWindowMask];
|
||||||
|
// auto inner = [window contentLayoutRect];
|
||||||
|
// auto full = [view frame];
|
||||||
|
// _public->_customTitleHeight = qMax(qRound(full.size.height - inner.size.height), 0);
|
||||||
|
|
||||||
|
_useNativeTitle = true;
|
||||||
|
setWindowTitle(qsl("Telegram"));
|
||||||
|
#endif // !OS_MAC_OLD
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::Private::refreshWeakTitleReferences() {
|
||||||
|
if (!_nativeWindow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef OS_MAC_OLD
|
#ifndef OS_MAC_OLD
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:_observer selector:@selector(windowWillEnterFullScreen:) name:NSWindowWillEnterFullScreenNotification object:window];
|
@autoreleasepool {
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:_observer selector:@selector(windowWillExitFullScreen:) name:NSWindowWillExitFullScreenNotification object:window];
|
|
||||||
|
if (NSView *parent = [[_nativeWindow contentView] superview]) {
|
||||||
|
if (id titleWrap = FindClassInSubviews(parent, Q2NSString(strTitleWrapClass()))) {
|
||||||
|
if ([titleWrap respondsToSelector:@selector(setBackgroundColor:)]) {
|
||||||
|
if (id title = FindClassInSubviews(titleWrap, Q2NSString(strTitleClass()))) {
|
||||||
|
if ([title respondsToSelector:@selector(setAttributedStringValue:)]) {
|
||||||
|
_nativeTitleWrapWeak = titleWrap;
|
||||||
|
_nativeTitleWeak = title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // !OS_MAC_OLD
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::Private::updateNativeTitle() {
|
||||||
|
if (!_useNativeTitle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifndef OS_MAC_OLD
|
||||||
|
if (!_nativeTitleWrapWeak || !_nativeTitleWeak) {
|
||||||
|
refreshWeakTitleReferences();
|
||||||
|
}
|
||||||
|
if (_nativeTitleWrapWeak && _nativeTitleWeak) {
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
auto convertColor = [](QColor color) {
|
||||||
|
return [NSColor colorWithDeviceRed:color.redF() green:color.greenF() blue:color.blueF() alpha:color.alphaF()];
|
||||||
|
};
|
||||||
|
auto adjustFg = [](const style::color &st) {
|
||||||
|
// Weird thing with NSTextField taking NSAttributedString with
|
||||||
|
// NSForegroundColorAttributeName set to colorWithDeviceRed:green:blue
|
||||||
|
// with components all equal to 128 - it ignores it and prints black text!
|
||||||
|
auto color = st->c;
|
||||||
|
return (color.red() == 128 && color.green() == 128 && color.blue() == 128)
|
||||||
|
? QColor(129, 129, 129, color.alpha())
|
||||||
|
: color;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto active = _public->isActiveWindow();
|
||||||
|
auto bgColor = (active ? st::titleBgActive : st::titleBg)->c;
|
||||||
|
auto fgColor = adjustFg(active ? st::titleFgActive : st::titleFg);
|
||||||
|
|
||||||
|
auto bgConverted = convertColor(bgColor);
|
||||||
|
auto fgConverted = convertColor(fgColor);
|
||||||
|
[_nativeTitleWrapWeak setBackgroundColor:bgConverted];
|
||||||
|
|
||||||
|
auto title = Q2NSString(_public->windowTitle());
|
||||||
|
NSDictionary *attributes = _inFullScreen
|
||||||
|
? nil
|
||||||
|
: [NSDictionary dictionaryWithObjectsAndKeys: fgConverted, NSForegroundColorAttributeName, bgConverted, NSBackgroundColorAttributeName, nil];
|
||||||
|
NSAttributedString *string = [[NSAttributedString alloc] initWithString:title attributes:attributes];
|
||||||
|
[_nativeTitleWeak setAttributedStringValue:string];
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif // !OS_MAC_OLD
|
#endif // !OS_MAC_OLD
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,10 +302,12 @@ bool MainWindow::Private::clipboardHasText() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::Private::willEnterFullScreen() {
|
void MainWindow::Private::willEnterFullScreen() {
|
||||||
|
_inFullScreen = true;
|
||||||
_public->setTitleVisible(false);
|
_public->setTitleVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::Private::willExitFullScreen() {
|
void MainWindow::Private::willExitFullScreen() {
|
||||||
|
_inFullScreen = false;
|
||||||
_public->setTitleVisible(true);
|
_public->setTitleVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,6 +343,12 @@ MainWindow::MainWindow()
|
|||||||
trayImgSel = st::macTrayIcon.instance(QColor(255, 255, 255), dbisOne);
|
trayImgSel = st::macTrayIcon.instance(QColor(255, 255, 255), dbisOne);
|
||||||
|
|
||||||
_hideAfterFullScreenTimer.setCallback([this] { hideAndDeactivate(); });
|
_hideAfterFullScreenTimer.setCallback([this] { hideAndDeactivate(); });
|
||||||
|
|
||||||
|
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &data) {
|
||||||
|
if (data.paletteChanged()) {
|
||||||
|
_private->updateNativeTitle();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::closeWithoutDestroy() {
|
void MainWindow::closeWithoutDestroy() {
|
||||||
@ -242,14 +369,15 @@ void MainWindow::stateChangedHook(Qt::WindowState state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::handleActiveChangedHook() {
|
||||||
|
InvokeQueued(this, [this] { _private->updateNativeTitle(); });
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::initHook() {
|
void MainWindow::initHook() {
|
||||||
_customTitleHeight = 0;
|
_customTitleHeight = 0;
|
||||||
if (auto view = reinterpret_cast<NSView*>(winId())) {
|
if (auto view = reinterpret_cast<NSView*>(winId())) {
|
||||||
if (auto window = [view window]) {
|
if (auto window = [view window]) {
|
||||||
if ([window respondsToSelector:@selector(contentLayoutRect)]
|
_private->setNativeWindow(window, view);
|
||||||
&& [window respondsToSelector:@selector(setTitlebarAppearsTransparent:)]) {
|
|
||||||
_private->initCustomTitle(window, view);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -345,7 +473,8 @@ void _placeCounter(QImage &img, int size, int count, style::color bg, style::col
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateTitleCounter() {
|
void MainWindow::updateTitleCounter() {
|
||||||
setWindowTitle(titleVisible() ? QString() : titleText());
|
//setWindowTitle(titleVisible() ? QString() : titleText());
|
||||||
|
_private->setWindowTitle(titleText());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::unreadCounterChangedHook() {
|
void MainWindow::unreadCounterChangedHook() {
|
||||||
|
@ -122,5 +122,7 @@ QString strNotificationAboutThemeChange();
|
|||||||
QString strNotificationAboutScreenLocked();
|
QString strNotificationAboutScreenLocked();
|
||||||
QString strNotificationAboutScreenUnlocked();
|
QString strNotificationAboutScreenUnlocked();
|
||||||
QString strStyleOfInterface();
|
QString strStyleOfInterface();
|
||||||
|
QString strTitleWrapClass();
|
||||||
|
QString strTitleClass();
|
||||||
|
|
||||||
bool psLaunchMaps(const LocationCoords &coords);
|
bool psLaunchMaps(const LocationCoords &coords);
|
||||||
|
@ -467,3 +467,13 @@ QString strStyleOfInterface() {
|
|||||||
const uint32 letters[] = { 0xEF004041, 0x4C007F70, 0x1F007A70, 0x9E00A76C, 0x8500D165, 0x2E003749, 0x7B00526E, 0x3400E774, 0x3C00FA65, 0x6200B172, 0xF7001D66, 0x0B002961, 0x71008C63, 0x86005465, 0xA3006F53, 0x11006174, 0xCD001779, 0x8200556C, 0x6C009B65 };
|
const uint32 letters[] = { 0xEF004041, 0x4C007F70, 0x1F007A70, 0x9E00A76C, 0x8500D165, 0x2E003749, 0x7B00526E, 0x3400E774, 0x3C00FA65, 0x6200B172, 0xF7001D66, 0x0B002961, 0x71008C63, 0x86005465, 0xA3006F53, 0x11006174, 0xCD001779, 0x8200556C, 0x6C009B65 };
|
||||||
return strMakeFromLetters(letters);
|
return strMakeFromLetters(letters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString strTitleWrapClass() {
|
||||||
|
const uint32 letters[] = { 0x4B00F54E, 0x2500A853, 0x2D008154, 0x4600EF69, 0x15006B74, 0xB900E86C, 0x66008A65, 0x3200B262, 0x9F00DC61, 0xA0009E72, 0xCF00EE43, 0x5600316F, 0x9100A76E, 0xBB000A74, 0xB6002661, 0xC7000769, 0x6200386E, 0x6B006D65, 0x1200C572, 0x41009156, 0x3D005569, 0xFE008C65, 0xB800D477 };
|
||||||
|
return strMakeFromLetters(letters);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString strTitleClass() {
|
||||||
|
const uint32 letters[] = { 0xF900894E, 0xF300BF53, 0x63009554, 0xEA008965, 0xEB004A78, 0x2E006074, 0xEC008446, 0x5C00DB69, 0x3C00CC65, 0x6F005D6C, 0x6400A064 };
|
||||||
|
return strMakeFromLetters(letters);
|
||||||
|
}
|
||||||
|
@ -173,6 +173,7 @@ void MainWindow::handleActiveChanged() {
|
|||||||
}
|
}
|
||||||
App::CallDelayed(1, this, [this] {
|
App::CallDelayed(1, this, [this] {
|
||||||
updateTrayMenu();
|
updateTrayMenu();
|
||||||
|
handleActiveChangedHook();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +112,9 @@ protected:
|
|||||||
virtual void updateIsActiveHook() {
|
virtual void updateIsActiveHook() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void handleActiveChangedHook() {
|
||||||
|
}
|
||||||
|
|
||||||
void clearWidgets();
|
void clearWidgets();
|
||||||
virtual void clearWidgetsHook() {
|
virtual void clearWidgetsHook() {
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,7 @@
|
|||||||
}, {
|
}, {
|
||||||
'xcode_settings': {
|
'xcode_settings': {
|
||||||
'CLANG_CXX_LIBRARY': 'libc++',
|
'CLANG_CXX_LIBRARY': 'libc++',
|
||||||
|
'CLANG_ENABLE_OBJC_WEAK': 'YES',
|
||||||
'OTHER_LDFLAGS': [
|
'OTHER_LDFLAGS': [
|
||||||
'-framework', 'VideoToolbox',
|
'-framework', 'VideoToolbox',
|
||||||
'-framework', 'VideoDecodeAcceleration',
|
'-framework', 'VideoDecodeAcceleration',
|
||||||
|
Loading…
Reference in New Issue
Block a user