From 8e78cfed85016b3bae64c9938e8a20fb03545994 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 16 Jun 2016 18:17:39 +0300 Subject: [PATCH] Fixed Xcode build. When hiding fullscreen window first exit fullscreen. --- Telegram/SourceFiles/facades.cpp | 2 +- Telegram/SourceFiles/mainwindow.cpp | 8 +- Telegram/SourceFiles/mainwindow.h | 6 +- .../platform/mac/main_window_mac.h | 35 +- .../platform/mac/main_window_mac.mm | 1416 +++++------------ Telegram/SourceFiles/pspecific_mac.cpp | 455 ------ Telegram/SourceFiles/pspecific_mac_p.mm | 2 +- Telegram/SourceFiles/ui/scrollarea.h | 22 +- Telegram/SourceFiles/window/main_window.h | 5 +- Telegram/Telegram.xcodeproj/project.pbxproj | 86 + Telegram/Telegram.xcodeproj/qt_preprocess.mak | 12 +- 11 files changed, 551 insertions(+), 1498 deletions(-) diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 21ab5d2afe..03ba4065d5 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -276,7 +276,7 @@ bool hideWindowNoQuit() { if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) { return w->minimizeToTray(); } else if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) { - w->hide(); + w->closeWithoutDestroy(); w->updateIsActive(Global::OfflineBlurTimeout()); w->updateGlobalMenu(); return true; diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index aa0e4d4bf9..c4952508eb 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -417,7 +417,9 @@ void MainWindow::onInactiveTimer() { inactivePress(false); } -void MainWindow::stateChanged(Qt::WindowState state) { +void MainWindow::onStateChanged(Qt::WindowState state) { + stateChangedHook(state); + psUserActionDone(); updateIsActive((state == Qt::WindowMinimized) ? Global::OfflineBlurTimeout() : Global::OnlineFocusTimeout()); @@ -1069,7 +1071,7 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *e) { case QEvent::WindowStateChange: if (obj == this) { Qt::WindowState state = (windowState() & Qt::WindowMinimized) ? Qt::WindowMinimized : ((windowState() & Qt::WindowMaximized) ? Qt::WindowMaximized : ((windowState() & Qt::WindowFullScreen) ? Qt::WindowFullScreen : Qt::WindowNoState)); - stateChanged(state); + onStateChanged(state); } break; @@ -1107,7 +1109,7 @@ void MainWindow::mouseReleaseEvent(QMouseEvent *e) { bool MainWindow::minimizeToTray() { if (App::quitting() || !psHasTrayIcon()) return false; - hide(); + closeWithoutDestroy(); if (cPlatform() == dbipWindows && trayIcon && !cSeenTrayTooltip()) { trayIcon->showMessage(str_const_toString(AppName), lang(lng_tray_icon_text), QSystemTrayIcon::Information, 10000); cSetSeenTrayTooltip(true); diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h index a599bf0616..5a7826c61e 100644 --- a/Telegram/SourceFiles/mainwindow.h +++ b/Telegram/SourceFiles/mainwindow.h @@ -249,9 +249,7 @@ public: PeerData *ui_getPeerForMouseAction(); public slots: - void updateIsActive(int timeout = 0); - void stateChanged(Qt::WindowState state); void checkHistoryActivation(); @@ -289,7 +287,6 @@ public slots: void app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button); signals: - void resized(const QSize &size); void tempDirCleared(int task); void tempDirClearFailed(int task); @@ -297,6 +294,9 @@ signals: void imageLoaded(); +private slots: + void onStateChanged(Qt::WindowState state); + private: QPixmap grabInner(); diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.h b/Telegram/SourceFiles/platform/mac/main_window_mac.h index a2fe866c19..2bbe76dc40 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.h +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.h @@ -75,7 +75,7 @@ public: void psNotifyShown(NotifyWindow *w); void psPlatformNotify(HistoryItem *item, int32 fwdCount); - bool eventFilter(QObject *obj, QEvent *evt); + bool eventFilter(QObject *obj, QEvent *evt) override; void psUpdateCounter(); @@ -85,10 +85,11 @@ public: virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0; + void closeWithoutDestroy() override; + ~MainWindow(); public slots: - void psUpdateDelegate(); void psSavePosition(Qt::WindowState state = Qt::WindowActive); void psShowTrayMenu(); @@ -101,9 +102,12 @@ public slots: void psMacDelete(); void psMacSelectAll(); -protected: +private slots: + void onHideAfterFullScreen(); + +protected: + void stateChangedHook(Qt::WindowState state) override; - void psNotIdle() const; QImage psTrayIcon(bool selected = false) const; bool psHasTrayIcon() const { return trayIcon; @@ -112,8 +116,8 @@ protected: void psMacUpdateMenu(); bool posInited; - QSystemTrayIcon *trayIcon; - QMenu *trayIconMenu; + QSystemTrayIcon *trayIcon = nullptr; + QMenu *trayIconMenu = nullptr; QImage icon256, iconbig256; QIcon wndIcon; @@ -126,14 +130,27 @@ protected: QTimer psUpdatedPositionTimer; private: - struct PrivateData; - std_::unique_ptr _private; + MacPrivate _private; mutable bool psIdle; mutable QTimer psIdleTimer; + QTimer _hideAfterFullScreenTimer; + QMenuBar psMainMenu; - QAction *psLogout, *psUndo, *psRedo, *psCut, *psCopy, *psPaste, *psDelete, *psSelectAll, *psContacts, *psAddContact, *psNewGroup, *psNewChannel, *psShowTelegram; + QAction *psLogout = nullptr; + QAction *psUndo = nullptr; + QAction *psRedo = nullptr; + QAction *psCut = nullptr; + QAction *psCopy = nullptr; + QAction *psPaste = nullptr; + QAction *psDelete = nullptr; + QAction *psSelectAll = nullptr; + QAction *psContacts = nullptr; + QAction *psAddContact = nullptr; + QAction *psNewGroup = nullptr; + QAction *psNewChannel = nullptr; + QAction *psShowTelegram = nullptr; }; diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 3dc9e5ee18..d493c9cf77 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -16,12 +16,14 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #include "stdafx.h" -#include "pspecific_mac_p.h" +#include "platform/mac/main_window_mac.h" #include "mainwindow.h" #include "mainwidget.h" #include "application.h" #include "playerwidget.h" +#include "historywidget.h" +#include "localstorage.h" #include "lang.h" @@ -31,1080 +33,478 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include -@interface qVisualize : NSObject { -} +namespace Platform { -+ (id)str:(const QString &)str; -- (id)initWithString:(const QString &)str; - -+ (id)bytearr:(const QByteArray &)arr; -- (id)initWithByteArray:(const QByteArray &)arr; - -- (id)debugQuickLookObject; - -@end - -@implementation qVisualize { - NSString *value; -} - -+ (id)bytearr:(const QByteArray &)arr { - return [[qVisualize alloc] initWithByteArray:arr]; -} -- (id)initWithByteArray:(const QByteArray &)arr { - if (self = [super init]) { - value = [NSString stringWithUTF8String:arr.constData()]; - } - return self; -} - -+ (id)str:(const QString &)str { - return [[qVisualize alloc] initWithString:str]; -} -- (id)initWithString:(const QString &)str { - if (self = [super init]) { - value = [NSString stringWithUTF8String:str.toUtf8().constData()]; - } - return self; -} - -- (id)debugQuickLookObject { - return value; -} - -@end - -@interface ApplicationDelegate : NSObject { -} - -- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag; -- (void)applicationDidBecomeActive:(NSNotification *)aNotification; -- (void)receiveWakeNote:(NSNotification*)note; - -@end - -ApplicationDelegate *_sharedDelegate = nil; - -@implementation ApplicationDelegate { -} - -- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag { - if (App::wnd() && App::wnd()->isHidden()) App::wnd()->showFromTray(); - return YES; -} - -- (void)applicationDidBecomeActive:(NSNotification *)aNotification { - if (App::app()) App::app()->checkLocalTime(); -} - -- (void)receiveWakeNote:(NSNotification*)aNotification { - if (App::app()) App::app()->checkLocalTime(); -} - -@end - -class QNSString { -public: - QNSString(const QString &str) : _str([NSString stringWithUTF8String:str.toUtf8().constData()]) { - } - NSString *s() { - return _str; - } -private: - NSString *_str; -}; - -QNSString objc_lang(LangKey key) { - return QNSString(lang(key)); -} -QString objcString(NSString *str) { - return QString::fromUtf8([str cStringUsingEncoding:NSUTF8StringEncoding]); -} - -@interface ObserverHelper : NSObject { -} - -- (id) init:(PsMacWindowPrivate *)aWnd; -- (void) activeSpaceDidChange:(NSNotification *)aNotification; -- (void) darkModeChanged:(NSNotification *)aNotification; - -@end - -@interface NotifyHandler : NSObject { -} - -- (id) init:(PsMacWindowPrivate *)aWnd; - -- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification; - -- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification; - -@end - -class PsMacWindowData { -public: - - PsMacWindowData(PsMacWindowPrivate *wnd) : - wnd(wnd), - observerHelper([[ObserverHelper alloc] init:wnd]), - notifyHandler([[NotifyHandler alloc] init:wnd]) { - } - - void onNotifyClick(NSUserNotification *notification) { - NSDictionary *dict = [notification userInfo]; - NSNumber *peerObj = [dict objectForKey:@"peer"], *msgObj = [dict objectForKey:@"msgid"]; - unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0; - int msgId = msgObj ? [msgObj intValue] : 0; - wnd->notifyClicked(peerLong, msgId); - } - - void onNotifyReply(NSUserNotification *notification) { - NSDictionary *dict = [notification userInfo]; - NSNumber *peerObj = [dict objectForKey:@"peer"], *msgObj = [dict objectForKey:@"msgid"]; - unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0; - int msgId = msgObj ? [msgObj intValue] : 0; - wnd->notifyReplied(peerLong, msgId, [[[notification response] string] UTF8String]); - } - - ~PsMacWindowData() { - [observerHelper release]; - [notifyHandler release]; - } - - PsMacWindowPrivate *wnd; - ObserverHelper *observerHelper; - NotifyHandler *notifyHandler; -}; - -@implementation ObserverHelper { - PsMacWindowPrivate *wnd; -} - -- (id) init:(PsMacWindowPrivate *)aWnd { - if (self = [super init]) { - wnd = aWnd; - } - return self; -} - -- (void) activeSpaceDidChange:(NSNotification *)aNotification { - wnd->activeSpaceChanged(); -} - -- (void) darkModeChanged:(NSNotification *)aNotification { - wnd->darkModeChanged(); -} - -@end - -@implementation NotifyHandler { - PsMacWindowPrivate *wnd; -} - -- (id) init:(PsMacWindowPrivate *)aWnd { - if (self = [super init]) { - wnd = aWnd; - } - return self; -} - -- (void) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification { - NSNumber *instObj = [[notification userInfo] objectForKey:@"launch"]; - unsigned long long instLong = instObj ? [instObj unsignedLongLongValue] : 0; - DEBUG_LOG(("Received notification with instance %1").arg(instLong)); - if (instLong != Global::LaunchId()) { // other app instance notification - return; - } - if (notification.activationType == NSUserNotificationActivationTypeReplied) { - wnd->data->onNotifyReply(notification); - } else if (notification.activationType == NSUserNotificationActivationTypeContentsClicked) { - wnd->data->onNotifyClick(notification); - } - [center removeDeliveredNotification: notification]; -} - -- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification { - return YES; -} - -@end - -PsMacWindowPrivate::PsMacWindowPrivate() : data(new PsMacWindowData(this)) { - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:data->observerHelper selector:@selector(activeSpaceDidChange:) name:NSWorkspaceActiveSpaceDidChangeNotification object:nil]; - [[NSDistributedNotificationCenter defaultCenter] addObserver:data->observerHelper selector:@selector(darkModeChanged:) name:QNSString(strNotificationAboutThemeChange()).s() object:nil]; -} - -void PsMacWindowPrivate::setWindowBadge(const QString &str) { - [[NSApp dockTile] setBadgeLabel:QNSString(str).s()]; -} - -void PsMacWindowPrivate::startBounce() { - [NSApp requestUserAttention:NSInformationalRequest]; -} - -void PsMacWindowPrivate::updateDelegate() { - NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; - [center setDelegate:data->notifyHandler]; -} - -void objc_holdOnTop(WId winId) { - NSWindow *wnd = [reinterpret_cast(winId) window]; - [wnd setHidesOnDeactivate:NO]; -} - -bool objc_darkMode() { - NSDictionary *dict = [[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain]; - id style = [dict objectForKey:QNSString(strStyleOfInterface()).s()]; - BOOL darkModeOn = ( style && [style isKindOfClass:[NSString class]] && NSOrderedSame == [style caseInsensitiveCompare:@"dark"] ); - return darkModeOn ? true : false; -} - -void objc_showOverAll(WId winId, bool canFocus) { - NSWindow *wnd = [reinterpret_cast(winId) window]; - [wnd setLevel:NSPopUpMenuWindowLevel]; - if (!canFocus) { - [wnd setStyleMask:NSUtilityWindowMask | NSNonactivatingPanelMask]; - [wnd setCollectionBehavior:NSWindowCollectionBehaviorMoveToActiveSpace|NSWindowCollectionBehaviorStationary|NSWindowCollectionBehaviorFullScreenAuxiliary|NSWindowCollectionBehaviorIgnoresCycle]; +void MacPrivate::activeSpaceChanged() { + if (App::wnd()) { + App::wnd()->notifyActivateAll(); } } -void objc_bringToBack(WId winId) { - NSWindow *wnd = [reinterpret_cast(winId) window]; - [wnd setLevel:NSModalPanelWindowLevel]; +void MacPrivate::darkModeChanged() { + Notify::unreadCounterUpdated(); } -void objc_activateWnd(WId winId) { - NSWindow *wnd = [reinterpret_cast(winId) window]; - [wnd orderFront:wnd]; -} +void MacPrivate::notifyClicked(unsigned long long peer, int msgid) { + History *history = App::history(PeerId(peer)); -NSImage *qt_mac_create_nsimage(const QPixmap &pm); - -void PsMacWindowPrivate::showNotify(uint64 peer, int32 msgId, const QPixmap &pix, const QString &title, const QString &subtitle, const QString &msg, bool withReply) { - NSUserNotification *notification = [[NSUserNotification alloc] init]; - NSImage *img = qt_mac_create_nsimage(pix); - - DEBUG_LOG(("Sending notification with userinfo: peer %1, msgId %2 and instance %3").arg(peer).arg(msgId).arg(Global::LaunchId())); - [notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer],@"peer",[NSNumber numberWithInt:msgId],@"msgid",[NSNumber numberWithUnsignedLongLong:Global::LaunchId()],@"launch",nil]]; - - [notification setTitle:QNSString(title).s()]; - [notification setSubtitle:QNSString(subtitle).s()]; - [notification setInformativeText:QNSString(msg).s()]; - if ([notification respondsToSelector:@selector(setContentImage:)]) { - [notification setContentImage:img]; - } - - if (withReply && [notification respondsToSelector:@selector(setHasReplyButton:)]) { - [notification setHasReplyButton:YES]; - } - - [notification setSoundName:nil]; - - NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; - [center deliverNotification:notification]; - - if (img) [img release]; - [notification release]; -} - -void PsMacWindowPrivate::enableShadow(WId winId) { -// [[(NSView*)winId window] setStyleMask:NSBorderlessWindowMask]; -// [[(NSView*)winId window] setHasShadow:YES]; -} - -bool PsMacWindowPrivate::filterNativeEvent(void *event) { - NSEvent *e = static_cast(event); - if (e && [e type] == NSSystemDefined && [e subtype] == 8) { - int keyCode = (([e data1] & 0xFFFF0000) >> 16); - int keyFlags = ([e data1] & 0x0000FFFF); - int keyState = (((keyFlags & 0xFF00) >> 8)) == 0xA; - int keyRepeat = (keyFlags & 0x1); - - switch (keyCode) { - case NX_KEYTYPE_PLAY: - if (keyState == 0) { // Play pressed and released - if (App::main()) App::main()->player()->playPausePressed(); - return true; - } - break; - - case NX_KEYTYPE_FAST: - if (keyState == 0) { // Next pressed and released - if (App::main()) App::main()->player()->nextPressed(); - return true; - } - break; - - case NX_KEYTYPE_REWIND: - if (keyState == 0) { // Previous pressed and released - if (App::main()) App::main()->player()->prevPressed(); - return true; - } - break; - } - } - return false; -} - - -void PsMacWindowPrivate::clearNotifies(unsigned long long peer) { - NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; - if (peer) { - NSArray *notifies = [center deliveredNotifications]; - for (id notify in notifies) { - NSDictionary *dict = [notify userInfo]; - if ([[dict objectForKey:@"peer"] unsignedLongLongValue] == peer && [[dict objectForKey:@"launch"] unsignedLongLongValue] == Global::LaunchId()) { - [center removeDeliveredNotification:notify]; - } - } - } else { - [center removeAllDeliveredNotifications]; - } -} - -void objc_debugShowAlert(const QString &str) { - [[NSAlert alertWithMessageText:@"Debug Message" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", QNSString(str).s()] runModal]; -} - -void objc_outputDebugString(const QString &str) { - NSLog(@"%@", QNSString(str).s()); -} - -PsMacWindowPrivate::~PsMacWindowPrivate() { - delete data; -} - -bool objc_idleSupported() { - int64 idleTime = 0; - return objc_idleTime(idleTime); -} - -bool objc_idleTime(int64 &idleTime) { // taken from https://github.com/trueinteractions/tint/issues/53 - CFMutableDictionaryRef properties = 0; - CFTypeRef obj; - mach_port_t masterPort; - io_iterator_t iter; - io_registry_entry_t curObj; - - IOMasterPort(MACH_PORT_NULL, &masterPort); - - /* Get IOHIDSystem */ - IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOHIDSystem"), &iter); - if (iter == 0) { - return false; - } else { - curObj = IOIteratorNext(iter); - } - if (IORegistryEntryCreateCFProperties(curObj, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties != NULL) { - obj = CFDictionaryGetValue(properties, CFSTR("HIDIdleTime")); - CFRetain(obj); - } else { - return false; - } - - uint64 err = ~0L, result = err; - if (obj) { - CFTypeID type = CFGetTypeID(obj); - - if (type == CFDataGetTypeID()) { - CFDataGetBytes((CFDataRef) obj, CFRangeMake(0, sizeof(result)), (UInt8*)&result); - } else if (type == CFNumberGetTypeID()) { - CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt64Type, &result); - } else { - // error - } - - CFRelease(obj); - - if (result != err) { - result /= 1000000; // return as ms - } - } else { - // error - } - - CFRelease((CFTypeRef)properties); - IOObjectRelease(curObj); - IOObjectRelease(iter); - if (result == err) return false; - - idleTime = int64(result); - return true; -} - -@interface OpenWithApp : NSObject { - NSString *fullname; - NSURL *app; - NSImage *icon; -} -@property (nonatomic, retain) NSString *fullname; -@property (nonatomic, retain) NSURL *app; -@property (nonatomic, retain) NSImage *icon; -@end - -@implementation OpenWithApp -@synthesize fullname, app, icon; - -- (void) dealloc { - [fullname release]; - [app release]; - [icon release]; - [super dealloc]; -} - -@end - -@interface OpenFileWithInterface : NSObject { -} - -- (id) init:(NSString *)file; -- (BOOL) popupAtX:(int)x andY:(int)y; -- (void) itemChosen:(id)sender; -- (void) dealloc; - -@end - -@implementation OpenFileWithInterface { - NSString *toOpen; - - NSURL *defUrl; - NSString *defBundle, *defName, *defVersion; - NSImage *defIcon; - - NSMutableArray *apps; - - NSMenu *menu; -} - -- (void) fillAppByUrl:(NSURL*)url bundle:(NSString**)bundle name:(NSString**)name version:(NSString**)version icon:(NSImage**)icon { - NSBundle *b = [NSBundle bundleWithURL:url]; - if (b) { - NSString *path = [url path]; - *name = [[NSFileManager defaultManager] displayNameAtPath: path]; - if (!*name) *name = (NSString*)[b objectForInfoDictionaryKey:@"CFBundleDisplayName"]; - if (!*name) *name = (NSString*)[b objectForInfoDictionaryKey:@"CFBundleName"]; - if (*name) { - *bundle = [b bundleIdentifier]; - if (bundle) { - *version = (NSString*)[b objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; - *icon = [[NSWorkspace sharedWorkspace] iconForFile: path]; - if (*icon && [*icon isValid]) [*icon setSize: CGSizeMake(16., 16.)]; - return; - } - } - } - *bundle = *name = *version = nil; - *icon = nil; -} - -- (id) init:(NSString*)file { - toOpen = file; - if (self = [super init]) { - NSURL *url = [NSURL fileURLWithPath:file]; - defUrl = [[NSWorkspace sharedWorkspace] URLForApplicationToOpenURL:url]; - if (defUrl) { - [self fillAppByUrl:defUrl bundle:&defBundle name:&defName version:&defVersion icon:&defIcon]; - if (!defBundle || !defName) { - defUrl = nil; - } - } - NSArray *appsList = (NSArray*)LSCopyApplicationURLsForURL(CFURLRef(url), kLSRolesAll); - NSMutableDictionary *data = [NSMutableDictionary dictionaryWithCapacity:16]; - int fullcount = 0; - for (id app in appsList) { - if (fullcount > 15) break; - - NSString *bundle = nil, *name = nil, *version = nil; - NSImage *icon = nil; - [self fillAppByUrl:(NSURL*)app bundle:&bundle name:&name version:&version icon:&icon]; - if (bundle && name) { - if ([bundle isEqualToString:defBundle] && [version isEqualToString:defVersion]) continue; - NSString *key = [[NSArray arrayWithObjects:bundle, name, nil] componentsJoinedByString:@"|"]; - if (!version) version = @""; - - NSMutableDictionary *versions = (NSMutableDictionary*)[data objectForKey:key]; - if (!versions) { - versions = [NSMutableDictionary dictionaryWithCapacity:2]; - [data setValue:versions forKey:key]; - } - if (![versions objectForKey:version]) { - [versions setValue:[NSArray arrayWithObjects:name, icon, app, nil] forKey:version]; - ++fullcount; - } - } - } - if (fullcount || defUrl) { - apps = [NSMutableArray arrayWithCapacity:fullcount]; - for (id key in data) { - NSMutableDictionary *val = (NSMutableDictionary*)[data objectForKey:key]; - for (id ver in val) { - NSArray *app = (NSArray*)[val objectForKey:ver]; - OpenWithApp *a = [[OpenWithApp alloc] init]; - NSString *fullname = (NSString*)[app objectAtIndex:0], *version = (NSString*)ver; - BOOL showVersion = ([val count] > 1); - if (!showVersion) { - NSError *error = NULL; - NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^\\d+\\.\\d+\\.\\d+(\\.\\d+)?$" options:NSRegularExpressionCaseInsensitive error:&error]; - showVersion = ![regex numberOfMatchesInString:version options:NSMatchingWithoutAnchoringBounds range:{0,[version length]}]; - } - if (showVersion) fullname = [[NSArray arrayWithObjects:fullname, @" (", version, @")", nil] componentsJoinedByString:@""]; - [a setFullname:fullname]; - [a setIcon:(NSImage*)[app objectAtIndex:1]]; - [a setApp:(NSURL*)[app objectAtIndex:2]]; - [apps addObject:a]; - [a release]; - } - } - } - [apps sortUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"fullname" ascending:YES]]]; - [appsList release]; - menu = nil; - } - return self; -} - -- (BOOL) popupAtX:(int)x andY:(int)y { - if (![apps count] && !defName) return NO; - menu = [[NSMenu alloc] initWithTitle:@"Open With"]; - - int index = 0; - if (defName) { - NSMenuItem *item = [menu insertItemWithTitle:[[NSArray arrayWithObjects:defName, @" (default)", nil] componentsJoinedByString:@""] action:@selector(itemChosen:) keyEquivalent:@"" atIndex:index++]; - if (defIcon) [item setImage:defIcon]; - [item setTarget:self]; - [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; - } - if ([apps count]) { - for (id a in apps) { - OpenWithApp *app = (OpenWithApp*)a; - NSMenuItem *item = [menu insertItemWithTitle:[a fullname] action:@selector(itemChosen:) keyEquivalent:@"" atIndex:index++]; - if ([app icon]) [item setImage:[app icon]]; - [item setTarget:self]; - } - [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; - } - NSMenuItem *item = [menu insertItemWithTitle:objc_lang(lng_mac_choose_program_menu).s() action:@selector(itemChosen:) keyEquivalent:@"" atIndex:index++]; - [item setTarget:self]; - - [menu popUpMenuPositioningItem:nil atLocation:CGPointMake(x, y) inView:nil]; - - return YES; -} - -- (void) itemChosen:(id)sender { - NSArray *items = [menu itemArray]; - NSURL *url = nil; - for (int i = 0, l = [items count]; i < l; ++i) { - if ([items objectAtIndex:i] == sender) { - if (defName) i -= 2; - if (i < 0) { - url = defUrl; - } else if (i < int([apps count])) { - url = [(OpenWithApp*)[apps objectAtIndex:i] app]; - } - break; - } - } - if (url) { - [[NSWorkspace sharedWorkspace] openFile:toOpen withApplication:[url path]]; + App::wnd()->showFromTray(); + if (App::passcoded()) { + App::wnd()->setInnerFocus(); + App::wnd()->notifyClear(); } else { - objc_openFile(objcString(toOpen), true); + App::wnd()->hideSettings(); + bool tomsg = !history->peer->isUser() && (msgid > 0); + if (tomsg) { + HistoryItem *item = App::histItemById(peerToChannel(PeerId(peer)), MsgId(msgid)); + if (!item || !item->mentionsMe()) { + tomsg = false; + } + } + Ui::showPeerHistory(history, tomsg ? msgid : ShowAtUnreadMsgId); + App::wnd()->notifyClear(history); } } -- (void) dealloc { - if (apps) [apps release]; - [super dealloc]; - if (menu) [menu release]; +void MacPrivate::notifyReplied(unsigned long long peer, int msgid, const char *str) { + History *history = App::history(PeerId(peer)); + + MainWidget::MessageToSend message; + message.history = history; + message.textWithTags = { QString::fromUtf8(str), TextWithTags::Tags() }; + message.replyTo = (msgid > 0 && !history->peer->isUser()) ? msgid : 0; + message.silent = false; + message.clearDraft = false; + App::main()->sendMessage(message); } -@end +MainWindow::MainWindow() +: posInited(false) +, icon256(qsl(":/gui/art/icon256.png")) +, iconbig256(qsl(":/gui/art/iconbig256.png")) +, wndIcon(QPixmap::fromImage(iconbig256, Qt::ColorOnly)) { + QImage tray(qsl(":/gui/art/osxtray.png")); + trayImg = tray.copy(0, cRetina() ? 0 : tray.width() / 2, tray.width() / (cRetina() ? 2 : 4), tray.width() / (cRetina() ? 2 : 4)); + trayImgSel = tray.copy(tray.width() / (cRetina() ? 2 : 4), cRetina() ? 0 : tray.width() / 2, tray.width() / (cRetina() ? 2 : 4), tray.width() / (cRetina() ? 2 : 4)); -bool objc_showOpenWithMenu(int x, int y, const QString &f) { - NSString *file = QNSString(f).s(); - @try { - OpenFileWithInterface *menu = [[OpenFileWithInterface alloc] init:file]; - QRect r = QApplication::desktop()->screenGeometry(QPoint(x, y)); - y = r.y() + r.height() - y; - return !![menu popupAtX:x andY:y]; + _hideAfterFullScreenTimer.setSingleShot(true); + connect(&_hideAfterFullScreenTimer, SIGNAL(timeout()), this, SLOT(onHideAfterFullScreen())); +} + +void MainWindow::closeWithoutDestroy() { + NSWindow *nsWindow = [reinterpret_cast(winId()) window]; + bool isFullScreen = (([nsWindow styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask); + if (isFullScreen) { + _hideAfterFullScreenTimer.start(3000); + [nsWindow toggleFullScreen:nsWindow]; + } else { + hide(); } - @catch (NSException *exception) { +} + +void MainWindow::stateChangedHook(Qt::WindowState state) { + if (_hideAfterFullScreenTimer.isActive()) { + _hideAfterFullScreenTimer.stop(); + QTimer::singleShot(0, this, SLOT(onHideAfterFullScreen())); } - @finally { +} + +void MainWindow::onHideAfterFullScreen() { + hide(); +} + +QImage MainWindow::psTrayIcon(bool selected) const { + return selected ? trayImgSel : trayImg; +} + +void MainWindow::psShowTrayMenu() { +} + +void MainWindow::psRefreshTaskbarIcon() { +} + +void MainWindow::psTrayMenuUpdated() { +} + +void MainWindow::psSetupTrayIcon() { + if (!trayIcon) { + trayIcon = new QSystemTrayIcon(this); + + QIcon icon(QPixmap::fromImage(psTrayIcon(), Qt::ColorOnly)); + icon.addPixmap(QPixmap::fromImage(psTrayIcon(true), Qt::ColorOnly), QIcon::Selected); + + trayIcon->setIcon(icon); + trayIcon->setToolTip(str_const_toString(AppName)); + connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleTray(QSystemTrayIcon::ActivationReason)), Qt::UniqueConnection); + App::wnd()->updateTrayMenu(); } - return false; + psUpdateCounter(); + + trayIcon->show(); } -void objc_showInFinder(const QString &file, const QString &path) { - [[NSWorkspace sharedWorkspace] selectFile:QNSString(file).s() inFileViewerRootedAtPath:QNSString(path).s()]; +void MainWindow::psUpdateWorkmode() { + psSetupTrayIcon(); + if (cWorkMode() == dbiwmWindowOnly) { + if (trayIcon) { + trayIcon->setContextMenu(0); + delete trayIcon; + } + trayIcon = 0; + } + psUpdateDelegate(); + setWindowIcon(wndIcon); } -@interface NSURL(CompareUrls) +void _placeCounter(QImage &img, int size, int count, style::color bg, style::color color) { + if (!count) return; -- (BOOL) isEquivalent:(NSURL *)aURL; + QPainter p(&img); + QString cnt = (count < 100) ? QString("%1").arg(count) : QString("..%1").arg(count % 100, 2, 10, QChar('0')); + int32 cntSize = cnt.size(); -@end + p.setBrush(bg->b); + p.setPen(Qt::NoPen); + p.setRenderHint(QPainter::Antialiasing); + int32 fontSize, skip; + if (size == 22) { + skip = 1; + fontSize = 8; + } else { + skip = 2; + fontSize = 16; + } + style::font f(fontSize, 0, 0); + int32 w = f->width(cnt), d, r; + if (size == 22) { + d = (cntSize < 2) ? 3 : 2; + r = (cntSize < 2) ? 6 : 5; + } else { + d = (cntSize < 2) ? 6 : 5; + r = (cntSize < 2) ? 9 : 11; + } + p.drawRoundedRect(QRect(size - w - d * 2 - skip, size - f->height - skip, w + d * 2, f->height), r, r); -@implementation NSURL(CompareUrls) - -- (BOOL) isEquivalent:(NSURL *)aURL { - if ([self isEqual:aURL]) return YES; - if ([[self scheme] caseInsensitiveCompare:[aURL scheme]] != NSOrderedSame) return NO; - if ([[self host] caseInsensitiveCompare:[aURL host]] != NSOrderedSame) return NO; - if ([[self path] compare:[aURL path]] != NSOrderedSame) return NO; - if ([[self port] compare:[aURL port]] != NSOrderedSame) return NO; - if ([[self query] compare:[aURL query]] != NSOrderedSame) return NO; - return YES; + p.setCompositionMode(QPainter::CompositionMode_Source); + p.setFont(f->f); + p.setPen(color->p); + p.drawText(size - w - d - skip, size - f->height + f->ascent - skip, cnt); } -@end +void MainWindow::psUpdateCounter() { + int32 counter = App::histories().unreadBadge(); -@interface ChooseApplicationDelegate : NSObject { + setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram")); + setWindowIcon(wndIcon); + + QString cnt = (counter < 1000) ? QString("%1").arg(counter) : QString("..%1").arg(counter % 100, 2, 10, QChar('0')); + _private.setWindowBadge(counter ? cnt : QString()); + + if (trayIcon) { + bool muted = App::histories().unreadOnlyMuted(); + bool dm = objc_darkMode(); + + style::color bg = muted ? st::counterMuteBG : st::counterBG; + QIcon icon; + QImage img(psTrayIcon(dm)), imgsel(psTrayIcon(true)); + img.detach(); + imgsel.detach(); + int32 size = cRetina() ? 44 : 22; + _placeCounter(img, size, counter, bg, (dm && muted) ? st::counterMacInvColor : st::counterColor); + _placeCounter(imgsel, size, counter, st::white, st::counterMacInvColor); + icon.addPixmap(QPixmap::fromImage(img, Qt::ColorOnly)); + icon.addPixmap(QPixmap::fromImage(imgsel, Qt::ColorOnly), QIcon::Selected); + trayIcon->setIcon(icon); + } } -- (id) init:(NSArray *)recommendedApps withPanel:(NSOpenPanel *)creator withSelector:(NSPopUpButton *)menu withGood:(NSTextField *)goodLabel withBad:(NSTextField *)badLabel withIcon:(NSImageView *)badIcon withAccessory:(NSView *)acc; -- (BOOL) panel:(id)sender shouldEnableURL:(NSURL *)url; -- (void) panelSelectionDidChange:(id)sender; -- (void) menuDidClose; -- (void) dealloc; - -@end - -@implementation ChooseApplicationDelegate { - BOOL onlyRecommended; - NSArray *apps; - NSOpenPanel *panel; - NSPopUpButton *selector; - NSTextField *good, *bad; - NSImageView *icon; - NSString *recom; - NSView *accessory; +void MainWindow::psUpdateDelegate() { + _private.updateDelegate(); } -- (id) init:(NSArray *)recommendedApps withPanel:(NSOpenPanel *)creator withSelector:(NSPopUpButton *)menu withGood:(NSTextField *)goodLabel withBad:(NSTextField *)badLabel withIcon:(NSImageView *)badIcon withAccessory:(NSView *)acc { - if (self = [super init]) { - onlyRecommended = YES; - recom = [objc_lang(lng_mac_recommended_apps).s() copy]; - apps = recommendedApps; - panel = creator; - selector = menu; - good = goodLabel; - bad = badLabel; - icon = badIcon; - accessory = acc; - [selector setAction:@selector(menuDidClose)]; - } - return self; +void MainWindow::psInitSize() { + setMinimumWidth(st::wndMinWidth); + setMinimumHeight(st::wndMinHeight); + + TWindowPos pos(cWindowPos()); + QRect avail(QDesktopWidget().availableGeometry()); + bool maximized = false; + QRect geom(avail.x() + (avail.width() - st::wndDefWidth) / 2, avail.y() + (avail.height() - st::wndDefHeight) / 2, st::wndDefWidth, st::wndDefHeight); + if (pos.w && pos.h) { + QList screens = Application::screens(); + for (QList::const_iterator i = screens.cbegin(), e = screens.cend(); i != e; ++i) { + QByteArray name = (*i)->name().toUtf8(); + if (pos.moncrc == hashCrc32(name.constData(), name.size())) { + QRect screen((*i)->geometry()); + int32 w = screen.width(), h = screen.height(); + if (w >= st::wndMinWidth && h >= st::wndMinHeight) { + if (pos.w > w) pos.w = w; + if (pos.h > h) pos.h = h; + pos.x += screen.x(); + pos.y += screen.y(); + if (pos.x < screen.x() + screen.width() - 10 && pos.y < screen.y() + screen.height() - 10) { + geom = QRect(pos.x, pos.y, pos.w, pos.h); + } + } + break; + } + } + + if (pos.y < 0) pos.y = 0; + maximized = pos.maximized; + } + setGeometry(geom); } -- (BOOL) isRecommended:(NSURL *)url { - if (apps) { - for (id app in apps) { - if ([(NSURL*)app isEquivalent:url]) { - return YES; - } - } - } - return NO; +void MainWindow::psInitFrameless() { + psUpdatedPositionTimer.setSingleShot(true); + connect(&psUpdatedPositionTimer, SIGNAL(timeout()), this, SLOT(psSavePosition())); } -- (BOOL) panel:(id)sender shouldEnableURL:(NSURL *)url { - NSNumber *isDirectory; - if ([url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil] && isDirectory != nil && [isDirectory boolValue]) { - if (onlyRecommended) { - CFStringRef ext = CFURLCopyPathExtension((CFURLRef)url); - NSNumber *isPackage; - if ([url getResourceValue:&isPackage forKey:NSURLIsPackageKey error:nil] && isPackage != nil && [isPackage boolValue]) { - return [self isRecommended:url]; - } - } - return YES; - } - return NO; +void MainWindow::psSavePosition(Qt::WindowState state) { + if (state == Qt::WindowActive) state = windowHandle()->windowState(); + if (state == Qt::WindowMinimized || !posInited) return; + + TWindowPos pos(cWindowPos()), curPos = pos; + + if (state == Qt::WindowMaximized) { + curPos.maximized = 1; + } else { + QRect r(geometry()); + curPos.x = r.x(); + curPos.y = r.y(); + curPos.w = r.width(); + curPos.h = r.height(); + curPos.maximized = 0; + } + + int px = curPos.x + curPos.w / 2, py = curPos.y + curPos.h / 2, d = 0; + QScreen *chosen = 0; + QList screens = Application::screens(); + for (QList::const_iterator i = screens.cbegin(), e = screens.cend(); i != e; ++i) { + int dx = (*i)->geometry().x() + (*i)->geometry().width() / 2 - px; if (dx < 0) dx = -dx; + int dy = (*i)->geometry().y() + (*i)->geometry().height() / 2 - py; if (dy < 0) dy = -dy; + if (!chosen || dx + dy < d) { + d = dx + dy; + chosen = *i; + } + } + if (chosen) { + curPos.x -= chosen->geometry().x(); + curPos.y -= chosen->geometry().y(); + QByteArray name = chosen->name().toUtf8(); + curPos.moncrc = hashCrc32(name.constData(), name.size()); + } + + if (curPos.w >= st::wndMinWidth && curPos.h >= st::wndMinHeight) { + if (curPos.x != pos.x || curPos.y != pos.y || curPos.w != pos.w || curPos.h != pos.h || curPos.moncrc != pos.moncrc || curPos.maximized != pos.maximized) { + cSetWindowPos(curPos); + Local::writeSettings(); + } + } } -- (void) panelSelectionDidChange:(id)sender { - NSArray *urls = [panel URLs]; - if ([urls count]) { - if ([self isRecommended:[urls firstObject]]) { - [bad removeFromSuperview]; - [icon removeFromSuperview]; - [accessory addSubview:good]; - } else { - [good removeFromSuperview]; - [accessory addSubview:bad]; - [accessory addSubview:icon]; - } - } else { - [good removeFromSuperview]; - [bad removeFromSuperview]; - [icon removeFromSuperview]; - } +void MainWindow::psUpdatedPosition() { + psUpdatedPositionTimer.start(SaveWindowPositionTimeout); } -- (void) menuDidClose { - onlyRecommended = [[[selector selectedItem] title] isEqualToString:recom]; - [self refreshPanelTable]; -} +void MainWindow::psFirstShow() { + psUpdateMargins(); -- (BOOL) refreshDataInViews: (NSArray*)subviews { - for (id view in subviews) { - NSString *cls = [view className]; - if ([cls isEqualToString:QNSString(strNeedToReload()).s()]) { - [view reloadData]; - } else if ([cls isEqualToString:QNSString(strNeedToRefresh1()).s()] || [cls isEqualToString:QNSString(strNeedToRefresh2()).s()]) { - [view reloadData]; - return YES; - } else { - NSArray *next = [view subviews]; - if ([next count] && [self refreshDataInViews:next]) { - return YES; - } - } - } + bool showShadows = true; - return NO; -} + show(); + _private.enableShadow(winId()); + if (cWindowPos().maximized) { + setWindowState(Qt::WindowMaximized); + } + if ((cLaunchMode() == LaunchModeAutoStart && cStartMinimized()) || cStartInTray()) { + setWindowState(Qt::WindowMinimized); + if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) { + hide(); + } else { + show(); + } + showShadows = false; + } else { + show(); + } -- (void) refreshPanelTable { - [self refreshDataInViews:[[panel contentView] subviews]]; - [panel validateVisibleColumns]; -} + posInited = true; -- (void) dealloc { - if (apps) { - [apps release]; - [recom release]; - } - [super dealloc]; -} + // init global menu + QMenu *main = psMainMenu.addMenu(qsl("Telegram")); + main->addAction(lng_mac_menu_about_telegram(lt_telegram, qsl("Telegram")), App::wnd()->getTitle(), SLOT(onAbout()))->setMenuRole(QAction::AboutQtRole); + main->addSeparator(); + QAction *prefs = main->addAction(lang(lng_mac_menu_preferences), App::wnd(), SLOT(showSettings()), QKeySequence(Qt::ControlModifier | Qt::Key_Comma)); + prefs->setMenuRole(QAction::PreferencesRole); -@end + QMenu *file = psMainMenu.addMenu(lang(lng_mac_menu_file)); + psLogout = file->addAction(lang(lng_mac_menu_logout), App::wnd(), SLOT(onLogout())); -void objc_openFile(const QString &f, bool openwith) { - NSString *file = QNSString(f).s(); - if (openwith || [[NSWorkspace sharedWorkspace] openFile:file] == NO) { - @try { - NSURL *url = [NSURL fileURLWithPath:file]; - NSString *ext = [url pathExtension]; - NSArray *names =[url pathComponents]; - NSString *name = [names count] ? [names lastObject] : @""; - NSArray *apps = (NSArray*)LSCopyApplicationURLsForURL(CFURLRef(url), kLSRolesAll); + QMenu *edit = psMainMenu.addMenu(lang(lng_mac_menu_edit)); + psUndo = edit->addAction(lang(lng_mac_menu_undo), this, SLOT(psMacUndo()), QKeySequence::Undo); + psRedo = edit->addAction(lang(lng_mac_menu_redo), this, SLOT(psMacRedo()), QKeySequence::Redo); + edit->addSeparator(); + psCut = edit->addAction(lang(lng_mac_menu_cut), this, SLOT(psMacCut()), QKeySequence::Cut); + psCopy = edit->addAction(lang(lng_mac_menu_copy), this, SLOT(psMacCopy()), QKeySequence::Copy); + psPaste = edit->addAction(lang(lng_mac_menu_paste), this, SLOT(psMacPaste()), QKeySequence::Paste); + psDelete = edit->addAction(lang(lng_mac_menu_delete), this, SLOT(psMacDelete()), QKeySequence(Qt::ControlModifier | Qt::Key_Backspace)); + edit->addSeparator(); + psSelectAll = edit->addAction(lang(lng_mac_menu_select_all), this, SLOT(psMacSelectAll()), QKeySequence::SelectAll); - NSOpenPanel *openPanel = [NSOpenPanel openPanel]; + QMenu *window = psMainMenu.addMenu(lang(lng_mac_menu_window)); + psContacts = window->addAction(lang(lng_mac_menu_contacts), App::wnd()->getTitle(), SLOT(onContacts())); + psAddContact = window->addAction(lang(lng_mac_menu_add_contact), App::wnd(), SLOT(onShowAddContact())); + window->addSeparator(); + psNewGroup = window->addAction(lang(lng_mac_menu_new_group), App::wnd(), SLOT(onShowNewGroup())); + psNewChannel = window->addAction(lang(lng_mac_menu_new_channel), App::wnd(), SLOT(onShowNewChannel())); + window->addSeparator(); + psShowTelegram = window->addAction(lang(lng_mac_menu_show), App::wnd(), SLOT(showFromTray())); - NSRect fullRect = { { 0., 0. }, { st::macAccessoryWidth, st::macAccessoryHeight } }; - NSView *accessory = [[NSView alloc] initWithFrame:fullRect]; - - [accessory setAutoresizesSubviews:YES]; - - NSPopUpButton *selector = [[NSPopUpButton alloc] init]; - [accessory addSubview:selector]; - [selector addItemWithTitle:objc_lang(lng_mac_recommended_apps).s()]; - [selector addItemWithTitle:objc_lang(lng_mac_all_apps).s()]; - [selector sizeToFit]; - - NSTextField *enableLabel = [[NSTextField alloc] init]; - [accessory addSubview:enableLabel]; - [enableLabel setStringValue:objc_lang(lng_mac_enable_filter).s()]; - [enableLabel setFont:[selector font]]; - [enableLabel setBezeled:NO]; - [enableLabel setDrawsBackground:NO]; - [enableLabel setEditable:NO]; - [enableLabel setSelectable:NO]; - [enableLabel sizeToFit]; - - NSRect selectorFrame = [selector frame], enableFrame = [enableLabel frame]; - enableFrame.size.width += st::macEnableFilterAdd; - enableFrame.origin.x = (fullRect.size.width - selectorFrame.size.width - enableFrame.size.width) / 2.; - selectorFrame.origin.x = (fullRect.size.width - selectorFrame.size.width + enableFrame.size.width) / 2.; - enableFrame.origin.y = fullRect.size.height - selectorFrame.size.height - st::macEnableFilterTop + (selectorFrame.size.height - enableFrame.size.height) / 2.; - selectorFrame.origin.y = fullRect.size.height - selectorFrame.size.height - st::macSelectorTop; - [enableLabel setFrame:enableFrame]; - [enableLabel setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin]; - [selector setFrame:selectorFrame]; - [selector setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin]; - - NSButton *button = [[NSButton alloc] init]; - [accessory addSubview:button]; - [button setButtonType:NSSwitchButton]; - [button setFont:[selector font]]; - [button setTitle:objc_lang(lng_mac_always_open_with).s()]; - [button sizeToFit]; - NSRect alwaysRect = [button frame]; - alwaysRect.origin.x = (fullRect.size.width - alwaysRect.size.width) / 2; - alwaysRect.origin.y = selectorFrame.origin.y - alwaysRect.size.height - st::macAlwaysThisAppTop; - [button setFrame:alwaysRect]; - [button setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin]; - NSTextField *goodLabel = [[NSTextField alloc] init]; - [goodLabel setStringValue:QNSString(lng_mac_this_app_can_open(lt_file, objcString(name))).s()]; - [goodLabel setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - [goodLabel setBezeled:NO]; - [goodLabel setDrawsBackground:NO]; - [goodLabel setEditable:NO]; - [goodLabel setSelectable:NO]; - [goodLabel sizeToFit]; - NSRect goodFrame = [goodLabel frame]; - goodFrame.origin.x = (fullRect.size.width - goodFrame.size.width) / 2.; - goodFrame.origin.y = alwaysRect.origin.y - goodFrame.size.height - st::macAppHintTop; - [goodLabel setFrame:goodFrame]; - - NSTextField *badLabel = [[NSTextField alloc] init]; - [badLabel setStringValue:QNSString(lng_mac_not_known_app(lt_file, objcString(name))).s()]; - [badLabel setFont:[goodLabel font]]; - [badLabel setBezeled:NO]; - [badLabel setDrawsBackground:NO]; - [badLabel setEditable:NO]; - [badLabel setSelectable:NO]; - [badLabel sizeToFit]; - NSImageView *badIcon = [[NSImageView alloc] init]; - NSImage *badImage = [NSImage imageNamed:NSImageNameCaution]; - [badIcon setImage:badImage]; - [badIcon setFrame:NSMakeRect(0, 0, st::macCautionIconSize, st::macCautionIconSize)]; - - NSRect badFrame = [badLabel frame], badIconFrame = [badIcon frame]; - badFrame.origin.x = (fullRect.size.width - badFrame.size.width + badIconFrame.size.width) / 2.; - badIconFrame.origin.x = (fullRect.size.width - badFrame.size.width - badIconFrame.size.width) / 2.; - badFrame.origin.y = alwaysRect.origin.y - badFrame.size.height - st::macAppHintTop; - badIconFrame.origin.y = badFrame.origin.y; - [badLabel setFrame:badFrame]; - [badIcon setFrame:badIconFrame]; - - [openPanel setAccessoryView:accessory]; - - ChooseApplicationDelegate *delegate = [[ChooseApplicationDelegate alloc] init:apps withPanel:openPanel withSelector:selector withGood:goodLabel withBad:badLabel withIcon:badIcon withAccessory:accessory]; - [openPanel setDelegate:delegate]; - - [openPanel setCanChooseDirectories:NO]; - [openPanel setCanChooseFiles:YES]; - [openPanel setAllowsMultipleSelection:NO]; - [openPanel setResolvesAliases:YES]; - [openPanel setTitle:objc_lang(lng_mac_choose_app).s()]; - [openPanel setMessage:QNSString(lng_mac_choose_text(lt_file, objcString(name))).s()]; - - NSArray *appsPaths = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationDirectory inDomains:NSLocalDomainMask]; - if ([appsPaths count]) [openPanel setDirectoryURL:[appsPaths firstObject]]; - [openPanel beginWithCompletionHandler:^(NSInteger result){ - if (result == NSFileHandlingPanelOKButton) { - if ([[openPanel URLs] count] > 0) { - NSURL *app = [[openPanel URLs] objectAtIndex:0]; - NSString *path = [app path]; - if ([button state] == NSOnState) { - NSArray *UTIs = (NSArray *)UTTypeCreateAllIdentifiersForTag(kUTTagClassFilenameExtension, - (CFStringRef)ext, - nil); - for (NSString *UTI in UTIs) { - OSStatus result = LSSetDefaultRoleHandlerForContentType((CFStringRef)UTI, - kLSRolesAll, - (CFStringRef)[[NSBundle bundleWithPath:path] bundleIdentifier]); - DEBUG_LOG(("App Info: set default handler for '%1' UTI result: %2").arg(objcString(UTI)).arg(result)); - } - - [UTIs release]; - } - [[NSWorkspace sharedWorkspace] openFile:file withApplication:[app path]]; - } - } - [selector release]; - [button release]; - [enableLabel release]; - [goodLabel release]; - [badLabel release]; - [badIcon release]; - [accessory release]; - [delegate release]; - }]; - } - @catch (NSException *exception) { - [[NSWorkspace sharedWorkspace] openFile:file]; - } - @finally { - } - } -} - -void objc_start() { - _sharedDelegate = [[ApplicationDelegate alloc] init]; - [[NSApplication sharedApplication] setDelegate:_sharedDelegate]; - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: _sharedDelegate - selector: @selector(receiveWakeNote:) - name: NSWorkspaceDidWakeNotification object: NULL]; + psMacUpdateMenu(); } namespace { - NSURL *_downloadPathUrl = nil; -} - -void objc_finish() { - [_sharedDelegate release]; - if (_downloadPathUrl) { - [_downloadPathUrl stopAccessingSecurityScopedResource]; - _downloadPathUrl = nil; - } -} - -void objc_registerCustomScheme() { - #ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME - OSStatus result = LSSetDefaultHandlerForURLScheme(CFSTR("tg"), (CFStringRef)[[NSBundle mainBundle] bundleIdentifier]); - DEBUG_LOG(("App Info: set default handler for 'tg' scheme result: %1").arg(result)); - #endif -} - -BOOL _execUpdater(BOOL update = YES, const QString &crashreport = QString()) { - NSString *path = @"", *args = @""; - @try { - path = [[NSBundle mainBundle] bundlePath]; - if (!path) { - LOG(("Could not get bundle path!!")); - return NO; - } - path = [path stringByAppendingString:@"/Contents/Frameworks/Updater"]; - - NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:@"-workpath", QNSString(cWorkingDir()).s(), @"-procid", nil]; - [args addObject:[NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]]]; - if (cRestartingToSettings()) [args addObject:@"-tosettings"]; - if (!update) [args addObject:@"-noupdate"]; - if (cLaunchMode() == LaunchModeAutoStart) [args addObject:@"-autostart"]; - if (cDebug()) [args addObject:@"-debug"]; - if (cStartInTray()) [args addObject:@"-startintray"]; - if (cTestMode()) [args addObject:@"-testmode"]; - if (cDataFile() != qsl("data")) { - [args addObject:@"-key"]; - [args addObject:QNSString(cDataFile()).s()]; - } - if (!crashreport.isEmpty()) { - [args addObject:@"-crashreport"]; - [args addObject:QNSString(crashreport).s()]; - } - - DEBUG_LOG(("Application Info: executing %1 %2").arg(objcString(path)).arg(objcString([args componentsJoinedByString:@" "]))); - Logs::closeMain(); - SignalHandlers::finish(); - if (![NSTask launchedTaskWithLaunchPath:path arguments:args]) { - DEBUG_LOG(("Task not launched while executing %1 %2").arg(objcString(path)).arg(objcString([args componentsJoinedByString:@" "]))); - return NO; + void _sendKeySequence(Qt::Key key, Qt::KeyboardModifiers modifiers = Qt::NoModifier) { + QWidget *focused = QApplication::focusWidget(); + if (qobject_cast(focused) || qobject_cast(focused) || qobject_cast(focused)) { + QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyPress, key, modifiers)); + QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyRelease, key, modifiers)); } } - @catch (NSException *exception) { - LOG(("Exception caught while executing %1 %2").arg(objcString(path)).arg(objcString(args))); - return NO; - } - @finally { - } - return YES; -} - -bool objc_execUpdater() { - return !!_execUpdater(); -} - -void objc_execTelegram(const QString &crashreport) { - _execUpdater(NO, crashreport); -} - -void objc_activateProgram(WId winId) { - [NSApp activateIgnoringOtherApps:YES]; - if (winId) { - NSWindow *w = [reinterpret_cast(winId) window]; - [w makeKeyAndOrderFront:NSApp]; - } -} - -bool objc_moveFile(const QString &from, const QString &to) { - NSString *f = QNSString(from).s(), *t = QNSString(to).s(); - if ([[NSFileManager defaultManager] fileExistsAtPath:t]) { - NSData *data = [NSData dataWithContentsOfFile:f]; - if (data) { - if ([data writeToFile:t atomically:YES]) { - if ([[NSFileManager defaultManager] removeItemAtPath:f error:nil]) { - return true; - } - } - } - } else { - if ([[NSFileManager defaultManager] moveItemAtPath:f toPath:t error:nil]) { - return true; + void _forceDisabled(QAction *action, bool disabled) { + if (action->isEnabled()) { + if (disabled) action->setDisabled(true); + } else if (!disabled) { + action->setDisabled(false); } } +} + +void MainWindow::psMacUndo() { + _sendKeySequence(Qt::Key_Z, Qt::ControlModifier); +} + +void MainWindow::psMacRedo() { + _sendKeySequence(Qt::Key_Z, Qt::ControlModifier | Qt::ShiftModifier); +} + +void MainWindow::psMacCut() { + _sendKeySequence(Qt::Key_X, Qt::ControlModifier); +} + +void MainWindow::psMacCopy() { + _sendKeySequence(Qt::Key_C, Qt::ControlModifier); +} + +void MainWindow::psMacPaste() { + _sendKeySequence(Qt::Key_V, Qt::ControlModifier); +} + +void MainWindow::psMacDelete() { + _sendKeySequence(Qt::Key_Delete); +} + +void MainWindow::psMacSelectAll() { + _sendKeySequence(Qt::Key_A, Qt::ControlModifier); +} + +bool MainWindow::psHandleTitle() { return false; } -void objc_deleteDir(const QString &dir) { - [[NSFileManager defaultManager] removeItemAtPath:QNSString(dir).s() error:nil]; +void MainWindow::psInitSysMenu() { } -double objc_appkitVersion() { - return NSAppKitVersionNumber; +void MainWindow::psUpdateSysMenu(Qt::WindowState state) { } -QString objc_appDataPath() { - NSURL *url = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil]; - if (url) { - return QString::fromUtf8([[url path] fileSystemRepresentation]) + '/' + str_const_toString(AppName) + '/'; +void MainWindow::psUpdateMargins() { +} + +void MainWindow::psMacUpdateMenu() { + if (!posInited) return; + + QWidget *focused = QApplication::focusWidget(); + bool isLogged = !!App::self(), canUndo = false, canRedo = false, canCut = false, canCopy = false, canPaste = false, canDelete = false, canSelectAll = false; + if (QLineEdit *edit = qobject_cast(focused)) { + canCut = canCopy = canDelete = edit->hasSelectedText(); + canSelectAll = !edit->text().isEmpty(); + canUndo = edit->isUndoAvailable(); + canRedo = edit->isRedoAvailable(); + canPaste = !Application::clipboard()->text().isEmpty(); + } else if (FlatTextarea *edit = qobject_cast(focused)) { + canCut = canCopy = canDelete = edit->textCursor().hasSelection(); + canSelectAll = !edit->isEmpty(); + canUndo = edit->isUndoAvailable(); + canRedo = edit->isRedoAvailable(); + canPaste = !Application::clipboard()->text().isEmpty(); + } else if (HistoryInner *list = qobject_cast(focused)) { + canCopy = list->canCopySelected(); + canDelete = list->canDeleteSelected(); } - return QString(); + _forceDisabled(psLogout, !isLogged && !App::passcoded()); + _forceDisabled(psUndo, !canUndo); + _forceDisabled(psRedo, !canRedo); + _forceDisabled(psCut, !canCut); + _forceDisabled(psCopy, !canCopy); + _forceDisabled(psPaste, !canPaste); + _forceDisabled(psDelete, !canDelete); + _forceDisabled(psSelectAll, !canSelectAll); + _forceDisabled(psContacts, !isLogged || App::passcoded()); + _forceDisabled(psAddContact, !isLogged || App::passcoded()); + _forceDisabled(psNewGroup, !isLogged || App::passcoded()); + _forceDisabled(psNewChannel, !isLogged || App::passcoded()); + _forceDisabled(psShowTelegram, App::wnd()->isActive(false)); } -QString objc_downloadPath() { - NSURL *url = [[NSFileManager defaultManager] URLForDirectory:NSDownloadsDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil]; - if (url) { - return QString::fromUtf8([[url path] fileSystemRepresentation]) + '/' + str_const_toString(AppName) + '/'; +void MainWindow::psFlash() { + _private.startBounce(); +} + +void MainWindow::psClearNotifies(PeerId peerId) { + _private.clearNotifies(peerId); +} + +void MainWindow::psActivateNotify(NotifyWindow *w) { + objc_activateWnd(w->winId()); +} + +bool MainWindow::psFilterNativeEvent(void *event) { + return _private.filterNativeEvent(event); +} + +void MainWindow::psNotifyShown(NotifyWindow *w) { + w->hide(); + objc_holdOnTop(w->winId()); + w->show(); + psShowOverAll(w, false); +} + +void MainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) { + QString title = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->name : qsl("Telegram Desktop"); + QString subtitle = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->notificationHeader() : QString(); + QPixmap pix = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->genUserpic(st::notifyMacPhotoSize) : QPixmap(); + QString msg = (!App::passcoded() && cNotifyView() <= dbinvShowPreview) ? (fwdCount < 2 ? item->notificationText() : lng_forward_messages(lt_count, fwdCount)) : lang(lng_notification_preview); + + bool withReply = !App::passcoded() && (cNotifyView() <= dbinvShowPreview) && item->history()->peer->canWrite(); + + _private.showNotify(item->history()->peer->id, item->id, pix, title, subtitle, msg, withReply); +} + +bool MainWindow::eventFilter(QObject *obj, QEvent *evt) { + QEvent::Type t = evt->type(); + if (t == QEvent::FocusIn || t == QEvent::FocusOut) { + if (qobject_cast(obj) || qobject_cast(obj) || qobject_cast(obj)) { + psMacUpdateMenu(); + } } - return QString(); + return Window::MainWindow::eventFilter(obj, evt); } -QString objc_currentCountry() { - NSLocale *currentLocale = [NSLocale currentLocale]; // get the current locale. - NSString *countryCode = [currentLocale objectForKey:NSLocaleCountryCode]; - return countryCode ? objcString(countryCode) : QString(); +MainWindow::~MainWindow() { } -QString objc_currentLang() { - NSLocale *currentLocale = [NSLocale currentLocale]; // get the current locale. - NSString *currentLang = [currentLocale objectForKey:NSLocaleLanguageCode]; - return currentLang ? objcString(currentLang) : QString(); -} - -QString objc_convertFileUrl(const QString &url) { - NSString *nsurl = [[[NSURL URLWithString: [NSString stringWithUTF8String: (qsl("file://") + url).toUtf8().constData()]] filePathURL] path]; - if (!nsurl) return QString(); - - return objcString(nsurl); -} - -QByteArray objc_downloadPathBookmark(const QString &path) { - return QByteArray(); -} - -QByteArray objc_pathBookmark(const QString &path) { - return QByteArray(); -} - -void objc_downloadPathEnableAccess(const QByteArray &bookmark) { -} - -objc_FileBookmark::objc_FileBookmark(const QByteArray &bookmark) { -} - -bool objc_FileBookmark::valid() const { - return true; -} - -bool objc_FileBookmark::enable() const { - return true; -} - -void objc_FileBookmark::disable() const { -} - -const QString &objc_FileBookmark::name(const QString &original) const { - return original; -} - -QByteArray objc_FileBookmark::bookmark() const { - return QByteArray(); -} - -objc_FileBookmark::~objc_FileBookmark() { -} +} // namespace diff --git a/Telegram/SourceFiles/pspecific_mac.cpp b/Telegram/SourceFiles/pspecific_mac.cpp index 59a3ff7f1d..dc7761b147 100644 --- a/Telegram/SourceFiles/pspecific_mac.cpp +++ b/Telegram/SourceFiles/pspecific_mac.cpp @@ -31,9 +31,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace { QStringList _initLogs; - bool frameless = true; - bool finished = true; - class _PsEventFilter : public QAbstractNativeEventFilter { public: _PsEventFilter() { @@ -50,430 +47,6 @@ namespace { }; -void MacPrivate::activeSpaceChanged() { - if (App::wnd()) { - App::wnd()->notifyActivateAll(); - } -} - -void MacPrivate::darkModeChanged() { - Notify::unreadCounterUpdated(); -} - -void MacPrivate::notifyClicked(unsigned long long peer, int msgid) { - History *history = App::history(PeerId(peer)); - - App::wnd()->showFromTray(); - if (App::passcoded()) { - App::wnd()->setInnerFocus(); - App::wnd()->notifyClear(); - } else { - App::wnd()->hideSettings(); - bool tomsg = !history->peer->isUser() && (msgid > 0); - if (tomsg) { - HistoryItem *item = App::histItemById(peerToChannel(PeerId(peer)), MsgId(msgid)); - if (!item || !item->mentionsMe()) { - tomsg = false; - } - } - Ui::showPeerHistory(history, tomsg ? msgid : ShowAtUnreadMsgId); - App::wnd()->notifyClear(history); - } -} - -void MacPrivate::notifyReplied(unsigned long long peer, int msgid, const char *str) { - History *history = App::history(PeerId(peer)); - - MainWidget::MessageToSend message; - message.history = history; - message.textWithTags = { QString::fromUtf8(str), TextWithTags::Tags() }; - message.replyTo = (msgid > 0 && !history->peer->isUser()) ? msgid : 0; - message.silent = false; - message.clearDraft = false; - App::main()->sendMessage(message); -} - -PsMainWindow::PsMainWindow(QWidget *parent) : QMainWindow(parent), -posInited(false), trayIcon(0), trayIconMenu(0), icon256(qsl(":/gui/art/icon256.png")), iconbig256(qsl(":/gui/art/iconbig256.png")), wndIcon(QPixmap::fromImage(iconbig256, Qt::ColorOnly)), -psLogout(0), psUndo(0), psRedo(0), psCut(0), psCopy(0), psPaste(0), psDelete(0), psSelectAll(0), psContacts(0), psAddContact(0), psNewGroup(0), psNewChannel(0), psShowTelegram(0) { - QImage tray(qsl(":/gui/art/osxtray.png")); - trayImg = tray.copy(0, cRetina() ? 0 : tray.width() / 2, tray.width() / (cRetina() ? 2 : 4), tray.width() / (cRetina() ? 2 : 4)); - trayImgSel = tray.copy(tray.width() / (cRetina() ? 2 : 4), cRetina() ? 0 : tray.width() / 2, tray.width() / (cRetina() ? 2 : 4), tray.width() / (cRetina() ? 2 : 4)); -} - -QImage PsMainWindow::psTrayIcon(bool selected) const { - return selected ? trayImgSel : trayImg; -} - -void PsMainWindow::psShowTrayMenu() { -} - -void PsMainWindow::psRefreshTaskbarIcon() { -} - -void PsMainWindow::psTrayMenuUpdated() { -} - -void PsMainWindow::psSetupTrayIcon() { - if (!trayIcon) { - trayIcon = new QSystemTrayIcon(this); - - QIcon icon(QPixmap::fromImage(psTrayIcon(), Qt::ColorOnly)); - icon.addPixmap(QPixmap::fromImage(psTrayIcon(true), Qt::ColorOnly), QIcon::Selected); - - trayIcon->setIcon(icon); - trayIcon->setToolTip(str_const_toString(AppName)); - connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleTray(QSystemTrayIcon::ActivationReason)), Qt::UniqueConnection); - App::wnd()->updateTrayMenu(); - } - psUpdateCounter(); - - trayIcon->show(); -} - -void PsMainWindow::psUpdateWorkmode() { - psSetupTrayIcon(); - if (cWorkMode() == dbiwmWindowOnly) { - if (trayIcon) { - trayIcon->setContextMenu(0); - delete trayIcon; - } - trayIcon = 0; - } - psUpdateDelegate(); - setWindowIcon(wndIcon); -} - -void _placeCounter(QImage &img, int size, int count, style::color bg, style::color color) { - if (!count) return; - - QPainter p(&img); - QString cnt = (count < 100) ? QString("%1").arg(count) : QString("..%1").arg(count % 100, 2, 10, QChar('0')); - int32 cntSize = cnt.size(); - - p.setBrush(bg->b); - p.setPen(Qt::NoPen); - p.setRenderHint(QPainter::Antialiasing); - int32 fontSize, skip; - if (size == 22) { - skip = 1; - fontSize = 8; - } else { - skip = 2; - fontSize = 16; - } - style::font f(fontSize, 0, 0); - int32 w = f->width(cnt), d, r; - if (size == 22) { - d = (cntSize < 2) ? 3 : 2; - r = (cntSize < 2) ? 6 : 5; - } else { - d = (cntSize < 2) ? 6 : 5; - r = (cntSize < 2) ? 9 : 11; - } - p.drawRoundedRect(QRect(size - w - d * 2 - skip, size - f->height - skip, w + d * 2, f->height), r, r); - - p.setCompositionMode(QPainter::CompositionMode_Source); - p.setFont(f->f); - p.setPen(color->p); - p.drawText(size - w - d - skip, size - f->height + f->ascent - skip, cnt); -} - -void PsMainWindow::psUpdateCounter() { - int32 counter = App::histories().unreadBadge(); - - setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram")); - setWindowIcon(wndIcon); - - QString cnt = (counter < 1000) ? QString("%1").arg(counter) : QString("..%1").arg(counter % 100, 2, 10, QChar('0')); - _private.setWindowBadge(counter ? cnt : QString()); - - if (trayIcon) { - bool muted = App::histories().unreadOnlyMuted(); - bool dm = objc_darkMode(); - - style::color bg = muted ? st::counterMuteBG : st::counterBG; - QIcon icon; - QImage img(psTrayIcon(dm)), imgsel(psTrayIcon(true)); - img.detach(); - imgsel.detach(); - int32 size = cRetina() ? 44 : 22; - _placeCounter(img, size, counter, bg, (dm && muted) ? st::counterMacInvColor : st::counterColor); - _placeCounter(imgsel, size, counter, st::white, st::counterMacInvColor); - icon.addPixmap(QPixmap::fromImage(img, Qt::ColorOnly)); - icon.addPixmap(QPixmap::fromImage(imgsel, Qt::ColorOnly), QIcon::Selected); - trayIcon->setIcon(icon); - } -} - -void PsMainWindow::psUpdateDelegate() { - _private.updateDelegate(); -} - -void PsMainWindow::psInitSize() { - setMinimumWidth(st::wndMinWidth); - setMinimumHeight(st::wndMinHeight); - - TWindowPos pos(cWindowPos()); - QRect avail(QDesktopWidget().availableGeometry()); - bool maximized = false; - QRect geom(avail.x() + (avail.width() - st::wndDefWidth) / 2, avail.y() + (avail.height() - st::wndDefHeight) / 2, st::wndDefWidth, st::wndDefHeight); - if (pos.w && pos.h) { - QList screens = Application::screens(); - for (QList::const_iterator i = screens.cbegin(), e = screens.cend(); i != e; ++i) { - QByteArray name = (*i)->name().toUtf8(); - if (pos.moncrc == hashCrc32(name.constData(), name.size())) { - QRect screen((*i)->geometry()); - int32 w = screen.width(), h = screen.height(); - if (w >= st::wndMinWidth && h >= st::wndMinHeight) { - if (pos.w > w) pos.w = w; - if (pos.h > h) pos.h = h; - pos.x += screen.x(); - pos.y += screen.y(); - if (pos.x < screen.x() + screen.width() - 10 && pos.y < screen.y() + screen.height() - 10) { - geom = QRect(pos.x, pos.y, pos.w, pos.h); - } - } - break; - } - } - - if (pos.y < 0) pos.y = 0; - maximized = pos.maximized; - } - setGeometry(geom); -} - -void PsMainWindow::psInitFrameless() { - psUpdatedPositionTimer.setSingleShot(true); - connect(&psUpdatedPositionTimer, SIGNAL(timeout()), this, SLOT(psSavePosition())); - - if (frameless) { - //setWindowFlags(Qt::FramelessWindowHint); - } -} - -void PsMainWindow::psSavePosition(Qt::WindowState state) { - if (state == Qt::WindowActive) state = windowHandle()->windowState(); - if (state == Qt::WindowMinimized || !posInited) return; - - TWindowPos pos(cWindowPos()), curPos = pos; - - if (state == Qt::WindowMaximized) { - curPos.maximized = 1; - } else { - QRect r(geometry()); - curPos.x = r.x(); - curPos.y = r.y(); - curPos.w = r.width(); - curPos.h = r.height(); - curPos.maximized = 0; - } - - int px = curPos.x + curPos.w / 2, py = curPos.y + curPos.h / 2, d = 0; - QScreen *chosen = 0; - QList screens = Application::screens(); - for (QList::const_iterator i = screens.cbegin(), e = screens.cend(); i != e; ++i) { - int dx = (*i)->geometry().x() + (*i)->geometry().width() / 2 - px; if (dx < 0) dx = -dx; - int dy = (*i)->geometry().y() + (*i)->geometry().height() / 2 - py; if (dy < 0) dy = -dy; - if (!chosen || dx + dy < d) { - d = dx + dy; - chosen = *i; - } - } - if (chosen) { - curPos.x -= chosen->geometry().x(); - curPos.y -= chosen->geometry().y(); - QByteArray name = chosen->name().toUtf8(); - curPos.moncrc = hashCrc32(name.constData(), name.size()); - } - - if (curPos.w >= st::wndMinWidth && curPos.h >= st::wndMinHeight) { - if (curPos.x != pos.x || curPos.y != pos.y || curPos.w != pos.w || curPos.h != pos.h || curPos.moncrc != pos.moncrc || curPos.maximized != pos.maximized) { - cSetWindowPos(curPos); - Local::writeSettings(); - } - } -} - -void PsMainWindow::psUpdatedPosition() { - psUpdatedPositionTimer.start(SaveWindowPositionTimeout); -} - -void PsMainWindow::psFirstShow() { - finished = false; - - psUpdateMargins(); - - bool showShadows = true; - - show(); - _private.enableShadow(winId()); - if (cWindowPos().maximized) { - setWindowState(Qt::WindowMaximized); - } - - if ((cLaunchMode() == LaunchModeAutoStart && cStartMinimized()) || cStartInTray()) { - setWindowState(Qt::WindowMinimized); - if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) { - hide(); - } else { - show(); - } - showShadows = false; - } else { - show(); - } - - posInited = true; - - // init global menu - QMenu *main = psMainMenu.addMenu(qsl("Telegram")); - main->addAction(lng_mac_menu_about_telegram(lt_telegram, qsl("Telegram")), App::wnd()->getTitle(), SLOT(onAbout()))->setMenuRole(QAction::AboutQtRole); - main->addSeparator(); - QAction *prefs = main->addAction(lang(lng_mac_menu_preferences), App::wnd(), SLOT(showSettings()), QKeySequence(Qt::ControlModifier | Qt::Key_Comma)); - prefs->setMenuRole(QAction::PreferencesRole); - - QMenu *file = psMainMenu.addMenu(lang(lng_mac_menu_file)); - psLogout = file->addAction(lang(lng_mac_menu_logout), App::wnd(), SLOT(onLogout())); - - QMenu *edit = psMainMenu.addMenu(lang(lng_mac_menu_edit)); - psUndo = edit->addAction(lang(lng_mac_menu_undo), this, SLOT(psMacUndo()), QKeySequence::Undo); - psRedo = edit->addAction(lang(lng_mac_menu_redo), this, SLOT(psMacRedo()), QKeySequence::Redo); - edit->addSeparator(); - psCut = edit->addAction(lang(lng_mac_menu_cut), this, SLOT(psMacCut()), QKeySequence::Cut); - psCopy = edit->addAction(lang(lng_mac_menu_copy), this, SLOT(psMacCopy()), QKeySequence::Copy); - psPaste = edit->addAction(lang(lng_mac_menu_paste), this, SLOT(psMacPaste()), QKeySequence::Paste); - psDelete = edit->addAction(lang(lng_mac_menu_delete), this, SLOT(psMacDelete()), QKeySequence(Qt::ControlModifier | Qt::Key_Backspace)); - edit->addSeparator(); - psSelectAll = edit->addAction(lang(lng_mac_menu_select_all), this, SLOT(psMacSelectAll()), QKeySequence::SelectAll); - - QMenu *window = psMainMenu.addMenu(lang(lng_mac_menu_window)); - psContacts = window->addAction(lang(lng_mac_menu_contacts), App::wnd()->getTitle(), SLOT(onContacts())); - psAddContact = window->addAction(lang(lng_mac_menu_add_contact), App::wnd(), SLOT(onShowAddContact())); - window->addSeparator(); - psNewGroup = window->addAction(lang(lng_mac_menu_new_group), App::wnd(), SLOT(onShowNewGroup())); - psNewChannel = window->addAction(lang(lng_mac_menu_new_channel), App::wnd(), SLOT(onShowNewChannel())); - window->addSeparator(); - psShowTelegram = window->addAction(lang(lng_mac_menu_show), App::wnd(), SLOT(showFromTray())); - - psMacUpdateMenu(); -} - -namespace { - void _sendKeySequence(Qt::Key key, Qt::KeyboardModifiers modifiers = Qt::NoModifier) { - QWidget *focused = QApplication::focusWidget(); - if (qobject_cast(focused) || qobject_cast(focused) || qobject_cast(focused)) { - QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyPress, key, modifiers)); - QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyRelease, key, modifiers)); - } - } - void _forceDisabled(QAction *action, bool disabled) { - if (action->isEnabled()) { - if (disabled) action->setDisabled(true); - } else if (!disabled) { - action->setDisabled(false); - } - } -} - -void PsMainWindow::psMacUndo() { - _sendKeySequence(Qt::Key_Z, Qt::ControlModifier); -} - -void PsMainWindow::psMacRedo() { - _sendKeySequence(Qt::Key_Z, Qt::ControlModifier | Qt::ShiftModifier); -} - -void PsMainWindow::psMacCut() { - _sendKeySequence(Qt::Key_X, Qt::ControlModifier); -} - -void PsMainWindow::psMacCopy() { - _sendKeySequence(Qt::Key_C, Qt::ControlModifier); -} - -void PsMainWindow::psMacPaste() { - _sendKeySequence(Qt::Key_V, Qt::ControlModifier); -} - -void PsMainWindow::psMacDelete() { - _sendKeySequence(Qt::Key_Delete); -} - -void PsMainWindow::psMacSelectAll() { - _sendKeySequence(Qt::Key_A, Qt::ControlModifier); -} - -bool PsMainWindow::psHandleTitle() { - return false; -} - -void PsMainWindow::psInitSysMenu() { -} - -void PsMainWindow::psUpdateSysMenu(Qt::WindowState state) { -} - -void PsMainWindow::psUpdateMargins() { -} - -void PsMainWindow::psMacUpdateMenu() { - if (!posInited) return; - - QWidget *focused = QApplication::focusWidget(); - bool isLogged = !!App::self(), canUndo = false, canRedo = false, canCut = false, canCopy = false, canPaste = false, canDelete = false, canSelectAll = false; - if (QLineEdit *edit = qobject_cast(focused)) { - canCut = canCopy = canDelete = edit->hasSelectedText(); - canSelectAll = !edit->text().isEmpty(); - canUndo = edit->isUndoAvailable(); - canRedo = edit->isRedoAvailable(); - canPaste = !Application::clipboard()->text().isEmpty(); - } else if (FlatTextarea *edit = qobject_cast(focused)) { - canCut = canCopy = canDelete = edit->textCursor().hasSelection(); - canSelectAll = !edit->isEmpty(); - canUndo = edit->isUndoAvailable(); - canRedo = edit->isRedoAvailable(); - canPaste = !Application::clipboard()->text().isEmpty(); - } else if (HistoryInner *list = qobject_cast(focused)) { - canCopy = list->canCopySelected(); - canDelete = list->canDeleteSelected(); - } - _forceDisabled(psLogout, !isLogged && !App::passcoded()); - _forceDisabled(psUndo, !canUndo); - _forceDisabled(psRedo, !canRedo); - _forceDisabled(psCut, !canCut); - _forceDisabled(psCopy, !canCopy); - _forceDisabled(psPaste, !canPaste); - _forceDisabled(psDelete, !canDelete); - _forceDisabled(psSelectAll, !canSelectAll); - _forceDisabled(psContacts, !isLogged || App::passcoded()); - _forceDisabled(psAddContact, !isLogged || App::passcoded()); - _forceDisabled(psNewGroup, !isLogged || App::passcoded()); - _forceDisabled(psNewChannel, !isLogged || App::passcoded()); - _forceDisabled(psShowTelegram, App::wnd()->isActive(false)); -} - -void PsMainWindow::psFlash() { - _private.startBounce(); -} - -PsMainWindow::~PsMainWindow() { - finished = true; -} - -void PsMainWindow::psClearNotifies(PeerId peerId) { - _private.clearNotifies(peerId); -} - -void PsMainWindow::psActivateNotify(NotifyWindow *w) { - objc_activateWnd(w->winId()); -} - -bool PsMainWindow::psFilterNativeEvent(void *event) { - return _private.filterNativeEvent(event); -} - namespace { QRect _monitorRect; uint64 _monitorLastGot = 0; @@ -496,34 +69,6 @@ void psBringToBack(QWidget *w) { objc_bringToBack(w->winId()); } -void PsMainWindow::psNotifyShown(NotifyWindow *w) { - w->hide(); - objc_holdOnTop(w->winId()); - w->show(); - psShowOverAll(w, false); -} - -void PsMainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) { - QString title = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->name : qsl("Telegram Desktop"); - QString subtitle = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->notificationHeader() : QString(); - QPixmap pix = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->genUserpic(st::notifyMacPhotoSize) : QPixmap(); - QString msg = (!App::passcoded() && cNotifyView() <= dbinvShowPreview) ? (fwdCount < 2 ? item->notificationText() : lng_forward_messages(lt_count, fwdCount)) : lang(lng_notification_preview); - - bool withReply = !App::passcoded() && (cNotifyView() <= dbinvShowPreview) && item->history()->peer->canWrite(); - - _private.showNotify(item->history()->peer->id, item->id, pix, title, subtitle, msg, withReply); -} - -bool PsMainWindow::eventFilter(QObject *obj, QEvent *evt) { - QEvent::Type t = evt->type(); - if (t == QEvent::FocusIn || t == QEvent::FocusOut) { - if (qobject_cast(obj) || qobject_cast(obj) || qobject_cast(obj)) { - psMacUpdateMenu(); - } - } - return QMainWindow::eventFilter(obj, evt); -} - QAbstractNativeEventFilter *psNativeEventFilter() { delete _psEventFilter; _psEventFilter = new _PsEventFilter(); diff --git a/Telegram/SourceFiles/pspecific_mac_p.mm b/Telegram/SourceFiles/pspecific_mac_p.mm index 3dc9e5ee18..f60aa96448 100644 --- a/Telegram/SourceFiles/pspecific_mac_p.mm +++ b/Telegram/SourceFiles/pspecific_mac_p.mm @@ -255,7 +255,7 @@ void objc_holdOnTop(WId winId) { bool objc_darkMode() { NSDictionary *dict = [[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain]; id style = [dict objectForKey:QNSString(strStyleOfInterface()).s()]; - BOOL darkModeOn = ( style && [style isKindOfClass:[NSString class]] && NSOrderedSame == [style caseInsensitiveCompare:@"dark"] ); + BOOL darkModeOn = (style && [style isKindOfClass:[NSString class]] && NSOrderedSame == [style caseInsensitiveCompare:@"dark"]); return darkModeOn ? true : false; } diff --git a/Telegram/SourceFiles/ui/scrollarea.h b/Telegram/SourceFiles/ui/scrollarea.h index 06ee0ccf55..1552cf5ade 100644 --- a/Telegram/SourceFiles/ui/scrollarea.h +++ b/Telegram/SourceFiles/ui/scrollarea.h @@ -166,15 +166,6 @@ public: ScrollArea(QWidget *parent, const style::flatScroll &st = st::scrollDef, bool handleTouch = true); - bool viewportEvent(QEvent *e); - void touchEvent(QTouchEvent *e); - - bool eventFilter(QObject *obj, QEvent *e); - - void resizeEvent(QResizeEvent *e); - void moveEvent(QMoveEvent *e); - void keyPressEvent(QKeyEvent *e); - int scrollWidth() const; int scrollHeight() const; int scrollLeftMax() const; @@ -190,13 +181,22 @@ public: void updateColors(const style::color &bar, const style::color &bg, const style::color &barOver, const style::color &bgOver); - bool focusNextPrevChild(bool next); + bool focusNextPrevChild(bool next) override; void setMovingByScrollBar(bool movingByScrollBar); + bool viewportEvent(QEvent *e) override; + void keyPressEvent(QKeyEvent *e) override; + ~ScrollArea(); protected: + bool eventFilter(QObject *obj, QEvent *e) override; + + void resizeEvent(QResizeEvent *e) override; + void moveEvent(QMoveEvent *e) override; + void touchEvent(QTouchEvent *e); + void enterEventHook(QEvent *e); void leaveEventHook(QEvent *e); @@ -223,7 +223,7 @@ signals: protected: - void scrollContentsBy(int dx, int dy); + void scrollContentsBy(int dx, int dy) override; private: diff --git a/Telegram/SourceFiles/window/main_window.h b/Telegram/SourceFiles/window/main_window.h index 99413ba2ff..ae15bd5f97 100644 --- a/Telegram/SourceFiles/window/main_window.h +++ b/Telegram/SourceFiles/window/main_window.h @@ -26,10 +26,13 @@ class MainWindow : public QMainWindow { public: MainWindow(); + virtual void closeWithoutDestroy(); + virtual ~MainWindow(); protected: - virtual void closeWithoutDestroy(); + virtual void stateChangedHook(Qt::WindowState state) { + } }; diff --git a/Telegram/Telegram.xcodeproj/project.pbxproj b/Telegram/Telegram.xcodeproj/project.pbxproj index 3540524c04..9eb17fbb6e 100644 --- a/Telegram/Telegram.xcodeproj/project.pbxproj +++ b/Telegram/Telegram.xcodeproj/project.pbxproj @@ -181,6 +181,9 @@ 07DE92AA1AA4928200A18F6F /* moc_autolockbox.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07DE92A91AA4928200A18F6F /* moc_autolockbox.cpp */; }; 07DE92AD1AA4928B00A18F6F /* moc_passcodebox.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07DE92AB1AA4928B00A18F6F /* moc_passcodebox.cpp */; }; 07DE92AE1AA4928B00A18F6F /* moc_passcodewidget.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07DE92AC1AA4928B00A18F6F /* moc_passcodewidget.cpp */; }; + 07E1B1911D12DB3F00722BC7 /* main_window_mac.mm in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07E1B1901D12DB3F00722BC7 /* main_window_mac.mm */; }; + 07E1B1931D12DED700722BC7 /* moc_main_window_mac.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07E1B1921D12DED700722BC7 /* moc_main_window_mac.cpp */; }; + 07E1B1961D12DFD200722BC7 /* main_window.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07E1B1941D12DFD200722BC7 /* main_window.cpp */; }; 07E373941CBBC11000934F77 /* peer_avatar_button.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07E373921CBBC11000934F77 /* peer_avatar_button.cpp */; }; 0CB7DE9A54CC9BF86FB7B5CA /* facade.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 6D50D70712776D7ED3B00E5C /* facade.cpp */; settings = {ATTRIBUTES = (); }; }; 0F7872E39EA570249D420912 /* moc_introwidget.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = A37C7E516201B0264A4CDA38 /* moc_introwidget.cpp */; settings = {ATTRIBUTES = (); }; }; @@ -631,6 +634,26 @@ 07DE92A91AA4928200A18F6F /* moc_autolockbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_autolockbox.cpp; path = GeneratedFiles/Debug/moc_autolockbox.cpp; sourceTree = SOURCE_ROOT; }; 07DE92AB1AA4928B00A18F6F /* moc_passcodebox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_passcodebox.cpp; path = GeneratedFiles/Debug/moc_passcodebox.cpp; sourceTree = SOURCE_ROOT; }; 07DE92AC1AA4928B00A18F6F /* moc_passcodewidget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_passcodewidget.cpp; path = GeneratedFiles/Debug/moc_passcodewidget.cpp; sourceTree = SOURCE_ROOT; }; + 07E1B1781D12DAF100722BC7 /* platform_main_window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = platform_main_window.h; path = SourceFiles/platform/platform_main_window.h; sourceTree = SOURCE_ROOT; }; + 07E1B1791D12DB0700722BC7 /* main_window_win.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main_window_win.cpp; path = SourceFiles/platform/win/main_window_win.cpp; sourceTree = SOURCE_ROOT; }; + 07E1B17A1D12DB0700722BC7 /* main_window_win.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = main_window_win.h; path = SourceFiles/platform/win/main_window_win.h; sourceTree = SOURCE_ROOT; }; + 07E1B17B1D12DB0700722BC7 /* windows_app_user_model_id.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = windows_app_user_model_id.cpp; path = SourceFiles/platform/win/windows_app_user_model_id.cpp; sourceTree = SOURCE_ROOT; }; + 07E1B17C1D12DB0700722BC7 /* windows_app_user_model_id.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = windows_app_user_model_id.h; path = SourceFiles/platform/win/windows_app_user_model_id.h; sourceTree = SOURCE_ROOT; }; + 07E1B17D1D12DB0700722BC7 /* windows_dlls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = windows_dlls.cpp; path = SourceFiles/platform/win/windows_dlls.cpp; sourceTree = SOURCE_ROOT; }; + 07E1B17E1D12DB0700722BC7 /* windows_dlls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = windows_dlls.h; path = SourceFiles/platform/win/windows_dlls.h; sourceTree = SOURCE_ROOT; }; + 07E1B17F1D12DB0700722BC7 /* windows_event_filter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = windows_event_filter.cpp; path = SourceFiles/platform/win/windows_event_filter.cpp; sourceTree = SOURCE_ROOT; }; + 07E1B1801D12DB0700722BC7 /* windows_event_filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = windows_event_filter.h; path = SourceFiles/platform/win/windows_event_filter.h; sourceTree = SOURCE_ROOT; }; + 07E1B1811D12DB0700722BC7 /* windows_toasts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = windows_toasts.cpp; path = SourceFiles/platform/win/windows_toasts.cpp; sourceTree = SOURCE_ROOT; }; + 07E1B1821D12DB0700722BC7 /* windows_toasts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = windows_toasts.h; path = SourceFiles/platform/win/windows_toasts.h; sourceTree = SOURCE_ROOT; }; + 07E1B1891D12DB2900722BC7 /* main_window_winrt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main_window_winrt.cpp; path = SourceFiles/platform/winrt/main_window_winrt.cpp; sourceTree = SOURCE_ROOT; }; + 07E1B18A1D12DB2900722BC7 /* main_window_winrt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = main_window_winrt.h; path = SourceFiles/platform/winrt/main_window_winrt.h; sourceTree = SOURCE_ROOT; }; + 07E1B18C1D12DB3500722BC7 /* main_window_linux.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main_window_linux.cpp; path = SourceFiles/platform/linux/main_window_linux.cpp; sourceTree = SOURCE_ROOT; }; + 07E1B18D1D12DB3500722BC7 /* main_window_linux.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = main_window_linux.h; path = SourceFiles/platform/linux/main_window_linux.h; sourceTree = SOURCE_ROOT; }; + 07E1B18F1D12DB3F00722BC7 /* main_window_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = main_window_mac.h; path = SourceFiles/platform/mac/main_window_mac.h; sourceTree = SOURCE_ROOT; }; + 07E1B1901D12DB3F00722BC7 /* main_window_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = main_window_mac.mm; path = SourceFiles/platform/mac/main_window_mac.mm; sourceTree = SOURCE_ROOT; }; + 07E1B1921D12DED700722BC7 /* moc_main_window_mac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_main_window_mac.cpp; path = GeneratedFiles/Debug/moc_main_window_mac.cpp; sourceTree = SOURCE_ROOT; }; + 07E1B1941D12DFD200722BC7 /* main_window.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main_window.cpp; path = SourceFiles/window/main_window.cpp; sourceTree = SOURCE_ROOT; }; + 07E1B1951D12DFD200722BC7 /* main_window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = main_window.h; path = SourceFiles/window/main_window.h; sourceTree = SOURCE_ROOT; }; 07E373921CBBC11000934F77 /* peer_avatar_button.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = peer_avatar_button.cpp; path = SourceFiles/ui/buttons/peer_avatar_button.cpp; sourceTree = SOURCE_ROOT; }; 07E373931CBBC11000934F77 /* peer_avatar_button.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = peer_avatar_button.h; path = SourceFiles/ui/buttons/peer_avatar_button.h; sourceTree = SOURCE_ROOT; }; 08A7682548FB7E671FF03822 /* boxshadow.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = boxshadow.cpp; path = SourceFiles/ui/boxshadow.cpp; sourceTree = ""; }; @@ -1076,6 +1099,8 @@ 076B1C581CBFC8DF002C0BC2 /* window */ = { isa = PBXGroup; children = ( + 07E1B1941D12DFD200722BC7 /* main_window.cpp */, + 07E1B1951D12DFD200722BC7 /* main_window.h */, 0716C97B1D058F2400797B22 /* section_memento.h */, 0716C97C1D058F2400797B22 /* section_widget.cpp */, 0716C97D1D058F2400797B22 /* section_widget.h */, @@ -1176,6 +1201,62 @@ name = toast; sourceTree = ""; }; + 07E1B1731D12DAC000722BC7 /* platform */ = { + isa = PBXGroup; + children = ( + 07E1B1751D12DACB00722BC7 /* linux */, + 07E1B1761D12DAD100722BC7 /* mac */, + 07E1B1771D12DAD700722BC7 /* win */, + 07E1B1881D12DB1500722BC7 /* winrt */, + 07E1B1781D12DAF100722BC7 /* platform_main_window.h */, + ); + name = platform; + sourceTree = ""; + }; + 07E1B1751D12DACB00722BC7 /* linux */ = { + isa = PBXGroup; + children = ( + 07E1B18C1D12DB3500722BC7 /* main_window_linux.cpp */, + 07E1B18D1D12DB3500722BC7 /* main_window_linux.h */, + ); + name = linux; + sourceTree = ""; + }; + 07E1B1761D12DAD100722BC7 /* mac */ = { + isa = PBXGroup; + children = ( + 07E1B18F1D12DB3F00722BC7 /* main_window_mac.h */, + 07E1B1901D12DB3F00722BC7 /* main_window_mac.mm */, + ); + name = mac; + sourceTree = ""; + }; + 07E1B1771D12DAD700722BC7 /* win */ = { + isa = PBXGroup; + children = ( + 07E1B1791D12DB0700722BC7 /* main_window_win.cpp */, + 07E1B17A1D12DB0700722BC7 /* main_window_win.h */, + 07E1B17B1D12DB0700722BC7 /* windows_app_user_model_id.cpp */, + 07E1B17C1D12DB0700722BC7 /* windows_app_user_model_id.h */, + 07E1B17D1D12DB0700722BC7 /* windows_dlls.cpp */, + 07E1B17E1D12DB0700722BC7 /* windows_dlls.h */, + 07E1B17F1D12DB0700722BC7 /* windows_event_filter.cpp */, + 07E1B1801D12DB0700722BC7 /* windows_event_filter.h */, + 07E1B1811D12DB0700722BC7 /* windows_toasts.cpp */, + 07E1B1821D12DB0700722BC7 /* windows_toasts.h */, + ); + name = win; + sourceTree = ""; + }; + 07E1B1881D12DB1500722BC7 /* winrt */ = { + isa = PBXGroup; + children = ( + 07E1B1891D12DB2900722BC7 /* main_window_winrt.cpp */, + 07E1B18A1D12DB2900722BC7 /* main_window_winrt.h */, + ); + name = winrt; + sourceTree = ""; + }; 07E373901CBBBFDE00934F77 /* buttons */ = { isa = PBXGroup; children = ( @@ -1316,6 +1397,7 @@ 5E35A03E5F2C51353EBCBF00 /* intro */, 1A6AA22F4A758C4B5F5138FB /* mtproto */, 076B1C5C1CBFC97D002C0BC2 /* overview */, + 07E1B1731D12DAC000722BC7 /* platform */, 0716C92C1D05898D00797B22 /* profile */, 0702E99F1CB8D290007A7495 /* serialize */, 579DA7AEF5751DF4988869A0 /* ui */, @@ -1453,6 +1535,7 @@ 1FE45A67215BEA2434F588E8 /* moc_layerwidget.cpp */, 1D7899ACAA9F973CADFA34C1 /* moc_localimageloader.cpp */, 07BE85111A20961F008ACB9F /* moc_localstorage.cpp */, + 07E1B1921D12DED700722BC7 /* moc_main_window_mac.cpp */, 3A220FD1AE5AD9FE3DC073A4 /* moc_mainwidget.cpp */, 6B46A0EE3C3B9D3B5A24946E /* moc_mainwindow.cpp */, 07A6933419927B160099CB9F /* moc_mediaview.cpp */, @@ -1835,6 +1918,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 07E1B1911D12DB3F00722BC7 /* main_window_mac.mm in Compile Sources */, 1299DDAE203A7EDFED9F5D6B /* main.cpp in Compile Sources */, D87463318C8E5211C8C8670A /* stdafx.cpp in Compile Sources */, 7BEFA1D273AD62772AA33D73 /* app.cpp in Compile Sources */, @@ -1872,6 +1956,7 @@ 0716C97A1D058C8600797B22 /* moc_report_box.cpp in Compile Sources */, 077A4AF81CA41C38002188D2 /* connection_auto.cpp in Compile Sources */, 4078D5D614EB3ECF7F1848C7 /* basic_types.cpp in Compile Sources */, + 07E1B1931D12DED700722BC7 /* moc_main_window_mac.cpp in Compile Sources */, 68FFEB7CA30BF0149161B809 /* mainwindow.cpp in Compile Sources */, 0716C9831D05931400797B22 /* moc_section_widget.cpp in Compile Sources */, 0CB7DE9A54CC9BF86FB7B5CA /* facade.cpp in Compile Sources */, @@ -2045,6 +2130,7 @@ 074968D01A44D14C00394F46 /* languagebox.cpp in Compile Sources */, 077A4AF91CA41C38002188D2 /* connection_http.cpp in Compile Sources */, 07BE85121A20961F008ACB9F /* moc_localstorage.cpp in Compile Sources */, + 07E1B1961D12DFD200722BC7 /* main_window.cpp in Compile Sources */, 07AF95F41AFD03B90060B057 /* qrc_telegram_emojis.cpp in Compile Sources */, 07C759721B1F7E2800662169 /* moc_autoupdater.cpp in Compile Sources */, 0716C9601D058C6600797B22 /* style_profile.cpp in Compile Sources */, diff --git a/Telegram/Telegram.xcodeproj/qt_preprocess.mak b/Telegram/Telegram.xcodeproj/qt_preprocess.mak index cbf4453908..5d7ef74901 100644 --- a/Telegram/Telegram.xcodeproj/qt_preprocess.mak +++ b/Telegram/Telegram.xcodeproj/qt_preprocess.mak @@ -95,6 +95,7 @@ compilers: GeneratedFiles/qrc_telegram.cpp\ GeneratedFiles/Debug/moc_layerwidget.cpp\ GeneratedFiles/Debug/moc_localimageloader.cpp\ GeneratedFiles/Debug/moc_localstorage.cpp\ + GeneratedFiles/Debug/moc_main_window_mac.cpp\ GeneratedFiles/Debug/moc_mainwidget.cpp\ GeneratedFiles/Debug/moc_mainwindow.cpp\ GeneratedFiles/Debug/moc_mediaview.cpp\ @@ -114,7 +115,6 @@ compilers: GeneratedFiles/qrc_telegram.cpp\ GeneratedFiles/Debug/moc_profile_settings_widget.cpp\ GeneratedFiles/Debug/moc_profile_shared_media_widget.cpp\ GeneratedFiles/Debug/moc_profile_widget.cpp\ - GeneratedFiles/Debug/moc_pspecific_mac.cpp\ GeneratedFiles/Debug/moc_report_box.cpp\ GeneratedFiles/Debug/moc_scrollarea.cpp\ GeneratedFiles/Debug/moc_section_widget.cpp\ @@ -232,6 +232,7 @@ compiler_moc_header_make_all: GeneratedFiles/Debug/moc_aboutbox.cpp\ GeneratedFiles/Debug/moc_layerwidget.cpp\ GeneratedFiles/Debug/moc_localimageloader.cpp\ GeneratedFiles/Debug/moc_localstorage.cpp\ + GeneratedFiles/Debug/moc_main_window_mac.cpp\ GeneratedFiles/Debug/moc_mainwidget.cpp\ GeneratedFiles/Debug/moc_mainwindow.cpp\ GeneratedFiles/Debug/moc_mediaview.cpp\ @@ -251,7 +252,6 @@ compiler_moc_header_make_all: GeneratedFiles/Debug/moc_aboutbox.cpp\ GeneratedFiles/Debug/moc_profile_settings_widget.cpp\ GeneratedFiles/Debug/moc_profile_shared_media_widget.cpp\ GeneratedFiles/Debug/moc_profile_widget.cpp\ - GeneratedFiles/Debug/moc_pspecific_mac.cpp\ GeneratedFiles/Debug/moc_report_box.cpp\ GeneratedFiles/Debug/moc_scrollarea.cpp\ GeneratedFiles/Debug/moc_section_widget.cpp\ @@ -312,6 +312,7 @@ compiler_moc_header_clean: GeneratedFiles/Debug/moc_layerwidget.cpp\ GeneratedFiles/Debug/moc_localimageloader.cpp\ GeneratedFiles/Debug/moc_localstorage.cpp\ + GeneratedFiles/Debug/moc_main_window_mac.cpp\ GeneratedFiles/Debug/moc_mainwidget.cpp\ GeneratedFiles/Debug/moc_mainwindow.cpp\ GeneratedFiles/Debug/moc_mediaview.cpp\ @@ -331,7 +332,6 @@ compiler_moc_header_clean: GeneratedFiles/Debug/moc_profile_settings_widget.cpp\ GeneratedFiles/Debug/moc_profile_shared_media_widget.cpp\ GeneratedFiles/Debug/moc_profile_widget.cpp\ - GeneratedFiles/Debug/moc_pspecific_mac.cpp\ GeneratedFiles/Debug/moc_report_box.cpp\ GeneratedFiles/Debug/moc_scrollarea.cpp\ GeneratedFiles/Debug/moc_section_widget.cpp\ @@ -483,6 +483,9 @@ GeneratedFiles/Debug/moc_localimageloader.cpp: SourceFiles/localimageloader.h GeneratedFiles/Debug/moc_localstorage.cpp: SourceFiles/localstorage.h $(MOC_FILE) SourceFiles/localstorage.h -o GeneratedFiles/Debug/moc_localstorage.cpp +GeneratedFiles/Debug/moc_main_window_mac.cpp: SourceFiles/platform/mac/main_window_mac.h + $(MOC_FILE) SourceFiles/platform/mac/main_window_mac.h -o GeneratedFiles/Debug/moc_main_window_mac.cpp + GeneratedFiles/Debug/moc_mainwidget.cpp: SourceFiles/mainwidget.h $(MOC_FILE) SourceFiles/mainwidget.h -o GeneratedFiles/Debug/moc_mainwidget.cpp @@ -540,9 +543,6 @@ GeneratedFiles/Debug/moc_profile_shared_media_widget.cpp: SourceFiles/profile/pr GeneratedFiles/Debug/moc_profile_widget.cpp: SourceFiles/profile/profile_widget.h $(MOC_FILE) SourceFiles/profile/profile_widget.h -o GeneratedFiles/Debug/moc_profile_widget.cpp -GeneratedFiles/Debug/moc_pspecific_mac.cpp: SourceFiles/pspecific_mac.h - $(MOC_FILE) SourceFiles/pspecific_mac.h -o GeneratedFiles/Debug/moc_pspecific_mac.cpp - GeneratedFiles/Debug/moc_report_box.cpp: SourceFiles/boxes/report_box.h $(MOC_FILE) SourceFiles/boxes/report_box.h -o GeneratedFiles/Debug/moc_report_box.cpp