diff --git a/Entitlements.plist b/Entitlements.plist
index 6cfee69ba5..a2d5d573f5 100644
--- a/Entitlements.plist
+++ b/Entitlements.plist
@@ -4,5 +4,9 @@
com.apple.security.device.camera
+ com.apple.developer.associated-domains
+
+ applinks:status.app
+
diff --git a/Status.entitlements b/Status.entitlements
deleted file mode 100644
index 961335b119..0000000000
--- a/Status.entitlements
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
- com.apple.developer.associated-domains
-
- applinks:status.app
-
-
-
diff --git a/src/nim_status_client.nim b/src/nim_status_client.nim
index 361196212e..b365d43383 100644
--- a/src/nim_status_client.nim
+++ b/src/nim_status_client.nim
@@ -131,7 +131,6 @@ proc mainProc() =
QResource.registerResource(app.applicationDirPath & resourcesPath)
# Register events objects
- let dockShowAppEvent = newStatusDockShowAppEventObject(singletonInstance.engine)
let osThemeEvent = newStatusOSThemeEventObject(singletonInstance.engine)
if not main_constants.IS_MACOS:
@@ -149,7 +148,6 @@ proc mainProc() =
singletonInstance.engine.setRootContextProperty("signals", signalsManagerQVariant)
singletonInstance.engine.setRootContextProperty("production", isProductionQVariant)
- app.installEventFilter(dockShowAppEvent)
app.installEventFilter(osThemeEvent)
app.installEventFilter(urlSchemeEvent)
@@ -161,7 +159,6 @@ proc mainProc() =
isExperimentalQVariant.delete()
signalsManagerQVariant.delete()
networkAccessFactory.delete()
- dockShowAppEvent.delete()
osThemeEvent.delete()
appController.delete()
statusFoundation.delete()
diff --git a/ui/main.qml b/ui/main.qml
index d0bc7fa7ad..5044476e6f 100644
--- a/ui/main.qml
+++ b/ui/main.qml
@@ -92,6 +92,11 @@ StatusWindow {
onWidthChanged: Qt.callLater(storeAppState)
onHeightChanged: Qt.callLater(storeAppState)
+ QtObject {
+ id: d
+ property int previousApplicationState: -1
+ }
+
Action {
shortcut: StandardKey.FullScreen
onTriggered: {
@@ -220,6 +225,20 @@ StatusWindow {
}
}
+ // On MacOS, explicitely restore the window on activating
+ Connections {
+ target: Qt.application
+ enabled: Qt.platform.os === Constants.mac
+ function onStateChanged() {
+ if (Qt.application.state == d.previousApplicationState
+ && Qt.application.state == Qt.ApplicationActive) {
+ applicationWindow.visible = true
+ applicationWindow.showNormal()
+ }
+ d.previousApplicationState = Qt.application.state
+ }
+ }
+
//TODO remove direct backend access
Connections {
target: singleInstance
@@ -358,15 +377,16 @@ StatusWindow {
onClose: {
if (loader.sourceComponent != app) {
+ Qt.quit()
+ return
+ }
+
+ if (localAccountSensitiveSettings.quitOnClose) {
Qt.quit();
- }
- else if (loader.sourceComponent == app) {
- if (localAccountSensitiveSettings.quitOnClose) {
- Qt.quit();
- } else {
- applicationWindow.visible = false;
- }
- }
+ return
+ }
+
+ applicationWindow.visible = false;
}
onMinimised: {
diff --git a/vendor/DOtherSide/lib/include/DOtherSide/DOtherSide.h b/vendor/DOtherSide/lib/include/DOtherSide/DOtherSide.h
index 885b985037..31dde1575c 100644
--- a/vendor/DOtherSide/lib/include/DOtherSide/DOtherSide.h
+++ b/vendor/DOtherSide/lib/include/DOtherSide/DOtherSide.h
@@ -998,7 +998,6 @@ DOS_API void DOS_CALL dos_singleinstance_delete(DosSingleInstance *vptr);
#pragma region Events exposed methods
-DOS_API DosEvent* dos_event_create_showAppEvent(DosQQmlApplicationEngine* vptr);
DOS_API DosEvent* dos_event_create_osThemeEvent(DosQQmlApplicationEngine* vptr);
DOS_API DosEvent* dos_event_create_urlSchemeEvent();
DOS_API void dos_event_delete(DosEvent* vptr);
diff --git a/vendor/DOtherSide/lib/include/DOtherSide/Status/DockShowAppEvent.h b/vendor/DOtherSide/lib/include/DOtherSide/Status/DockShowAppEvent.h
deleted file mode 100644
index f2833535a7..0000000000
--- a/vendor/DOtherSide/lib/include/DOtherSide/Status/DockShowAppEvent.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef STATUS_DOCK_SHOW_APP_EVENT_H
-#define STATUS_DOCK_SHOW_APP_EVENT_H
-
-#include "../DOtherSideTypes.h"
-
-#include
-#include
-
-namespace Status
-{
- class DockShowAppEvent : public QObject
- {
- Q_OBJECT
-
- public:
- DockShowAppEvent(DosQQmlApplicationEngine* vptr, QObject* parent = nullptr);
-
- protected:
- bool eventFilter(QObject* obj, QEvent* event) override;
-
- private:
- Qt::ApplicationState m_prevAppState;
- QQmlApplicationEngine* m_engine;
- };
-}
-
-#endif
diff --git a/vendor/DOtherSide/lib/src/DOtherSide.cpp b/vendor/DOtherSide/lib/src/DOtherSide.cpp
index 578b340816..b0989ee3cc 100644
--- a/vendor/DOtherSide/lib/src/DOtherSide.cpp
+++ b/vendor/DOtherSide/lib/src/DOtherSide.cpp
@@ -68,7 +68,6 @@
#include "DOtherSide/DosQQuickImageProvider.h"
#include "DOtherSide/DOtherSideSingleInstance.h"
-#include "DOtherSide/Status/DockShowAppEvent.h"
#include "DOtherSide/Status/OSThemeEvent.h"
#include "DOtherSide/Status/UrlSchemeEvent.h"
#include "DOtherSide/Status/OSNotification.h"
@@ -1553,11 +1552,6 @@ bool dos_singleinstance_isfirst(DosSingleInstance *vptr)
}
#pragma region Events
-::DosEvent* dos_event_create_showAppEvent(::DosQQmlApplicationEngine* vptr)
-{
- auto engine = static_cast(vptr);
- return new Status::DockShowAppEvent(engine);
-}
::DosEvent* dos_event_create_osThemeEvent(::DosQQmlApplicationEngine* vptr)
{
diff --git a/vendor/DOtherSide/lib/src/Status/AppDelegate.mm b/vendor/DOtherSide/lib/src/Status/AppDelegate.mm
index de91c3fca1..7179cf22e4 100644
--- a/vendor/DOtherSide/lib/src/Status/AppDelegate.mm
+++ b/vendor/DOtherSide/lib/src/Status/AppDelegate.mm
@@ -2,23 +2,25 @@
#include
#include
+#include
#import
+#import
-
-@interface AppDelegate: NSObject
+@interface StatusApplicationDelegate: NSObject
- (BOOL)application:(NSApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray> *restorableObjects))restorationHandler;
@end
-@implementation AppDelegate
-- (BOOL)application:(NSApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray> *))restorationHandler {
+@implementation StatusApplicationDelegate
+- (BOOL)application:(NSApplication *)application
+ continueUserActivity:(NSUserActivity *)userActivity
+ restorationHandler:(void (^)(NSArray> *))restorationHandler {
if (userActivity.activityType == NSUserActivityTypeBrowsingWeb) {
NSURL *url = userActivity.webpageURL;
- if (!url) {
+ if (!url)
return FALSE;
- }
QUrl deeplink = QUrl::fromNSURL(url);
// set it to nim
return TRUE;
@@ -26,14 +28,44 @@ continueUserActivity:(NSUserActivity *)userActivity
return FALSE;
}
+- (void)applicationDidFinishLaunching:(NSNotification *)notification
+{
+ qDebug() << "StatusApplicationDelegate::applicationDidFinishLaunching";
+}
+
@end
namespace app_delegate {
-void install()
-{
- NSApplication* applicationShared = [NSApplication sharedApplication];
- [applicationShared setDelegate:([[[AppDelegate alloc] init] autorelease])];
+void swizzle_appdelegate_method(SEL selector) {
+ Class originalClass = [NSApplication sharedApplication].delegate.class;
+ Class swizzledClass = [StatusApplicationDelegate class];
+
+ Method originalMethod = class_getInstanceMethod(originalClass, selector);
+ Method swizzledMethod = class_getInstanceMethod(swizzledClass, selector);
+
+ method_exchangeImplementations(originalMethod, swizzledMethod);
}
-}
\ No newline at end of file
+void install()
+{
+ /*
+ A simple solution to implement custom ApplicationDelegate would be to call `NSApplication::setDelegate`
+ with an instantse of StatusApplicationDelegate. But this will override Qt's ApplicationDelegate implementation
+ `QCocoaApplicationDelegate` (qtbase/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm).
+
+ Overriding breaks some Qt events like `QApplicationStateChangeEvent`. And I suppose (and pretty sure)
+ that this might also break other things.
+
+ Would be cool to simply inherit `QCocoaApplicationDelegate`, but it's only available in Qt's sources.
+
+ The solution here is to use "method swizzling" technique.
+ We replace the method of a class with own implementation.
+
+ In future we could contribute to Qt to add "continueUserActivity" event.
+ */
+ swizzle_appdelegate_method(@selector(applicationDidFinishLaunching:)); // for testing purposes (ApplicationDelegate works, method swizzled)
+ swizzle_appdelegate_method(@selector(application:continueUserActivity:restorationHandler:)); // for Univeral Links support
+}
+
+}
diff --git a/vendor/DOtherSide/lib/src/Status/DockShowAppEvent.cpp b/vendor/DOtherSide/lib/src/Status/DockShowAppEvent.cpp
deleted file mode 100644
index 2b1aa170b6..0000000000
--- a/vendor/DOtherSide/lib/src/Status/DockShowAppEvent.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "DOtherSide/Status/DockShowAppEvent.h"
-
-#include
-
-
-/*
- Code here is exactly the same as it was before, logic is not changed. I only
- put it in another form, nothing else. To match an improved flow for
- installing filters.
-*/
-
-using namespace Status;
-
-DockShowAppEvent::DockShowAppEvent(DosQQmlApplicationEngine* vptr,
- QObject* parent)
- : QObject(parent)
-{
- m_engine = static_cast(vptr);
-}
-
-bool DockShowAppEvent::eventFilter(QObject* obj, QEvent* event)
-{
-#ifdef Q_OS_MACOS
- if (event->type() == QEvent::ApplicationStateChange)
- {
- auto ev = static_cast(event);
- if (m_prevAppState == Qt::ApplicationActive
- && ev->applicationState() == Qt::ApplicationActive)
- {
- QObject* topLevelObj = m_engine->rootObjects().value(0);
- if(topLevelObj && topLevelObj->objectName() == "mainWindow")
- {
- QQuickWindow* window = qobject_cast(topLevelObj);
- if(window)
- {
- window->setVisible(true);
- window->showNormal();
- return true;
- }
- }
- }
- m_prevAppState = ev->applicationState();
- }
-#endif
-
- return QObject::eventFilter(obj, event);
-}
diff --git a/vendor/nimqml b/vendor/nimqml
index ab78548aa3..3f61ec4add 160000
--- a/vendor/nimqml
+++ b/vendor/nimqml
@@ -1 +1 @@
-Subproject commit ab78548aa3838fb51aff791d14203e29849ed200
+Subproject commit 3f61ec4addbd1e59c6936658258214a58b768c4a