PDA

View Full Version : Qt OS X closing application issue



papercut87
28th September 2015, 10:58
Hi All,

Recently i started to program Qt on OS X.
My simple application is composed by only one window with a system tray icon.
When the user press the closing button (x) on the top left corner, the application becomes hide.
I also connect an action from the tray icon menu to quit the application. Everything works fine with the expected behavior.

My only problem is that, the app also have the icon dock menu with the action "quit". This action is a native function provided by the OS.
What i would like to do is to "catch" this signal emit from that action.
Because seems that the quit from the dock icon is different from the CMD+Q action(i'm able to manage this signal in my overloaded function).

void MainWindow::closeEvent(QCloseEvent* event)
The quit from the Dock Menu seems like an interrupt(like SIGTERM) and the app quit in any case. If the application main window is shown, i don't want to close the app but simply hide the window.

Another weird thing is that when i press on quit from the Dock menu, the
closeEvent(QCloseEvent* event) function is called twice and if i ignore the close event
event->ignore() the app quit anyway.

Thanks to All in advance.

anda_skoa
28th September 2015, 13:10
You could check if there is native API to catch that event, if it is available to the native event filter used by the Qt application's event dispatcher, etc.

If it is indeed just a signal, then installing a signal handler might do the trick.

Cheers,
_

Rondog
28th September 2015, 14:44
Qt with OS X works swimmingly. Whatever is going on is likely your approach.

Can you post some code (particularly your main.cpp file) and anything related to creating and closing windows.

papercut87
2nd October 2015, 14:59
Ok, thanks for your help.
Like anda_skoa suggest me:
You could check if there is native API to catch that event, ...
i used the cocoa code(mixed with the Qt code) to manage the operation.
I registered another function instead of the system function related to the Exit action.

This operation can be done extending the QApplication class with a custom class.
For someone who's interested below the code:

In CustomAppClass.h that extend QApplication


#ifdef Q_OS_MAC
#include <objc/objc.h>
#include <objc/message.h>
void setupDockClickHandler();
int quitFromDockMenuHandler(id self, SEL _cmd,...);
#endif

in the .c file:


#ifdef Q_OS_MAC
void setupDockClickHandler() {
Class cls = objc_getClass("NSApplication");
objc_object *appInst = objc_msgSend((objc_object*)cls, sel_registerName("sharedApplication"));
if(appInst != NULL) {
objc_object* delegate = objc_msgSend(appInst, sel_registerName("delegate"));
Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class"));
SEL closeHandle = sel_registerName("applicationShouldTerminate:");
if (class_getInstanceMethod(delClass, closeHandle)) {
if (class_replaceMethod(delClass, closeHandle, (IMP)quitFromDockMenuHandler, "B@:"))
qDebug() << "Registered quit click handler (replaced original method)";
else
qWarning() << "Failed to replace method for quit click handler";
}
else {
if (class_addMethod(delClass, closeHandle, (IMP)quitFromDockMenuHandler,"B@:"))
qDebug() << "Registered quit click handler";
else
qWarning() << "Failed to register quit click handler";
}

}
}

int quitFromDockMenuHandler(id self,SEL _cmd,...) {
Q_UNUSED(self)
Q_UNUSED(_cmd)
qDebug() << "QUIT!";
((SingleApplication*)qApp)->onQuitAppAction();
/// Return NO (false) to suppress the default OS X actions
return 1;
}

void SingleApplication:: onQuitAppAction(){
emit sig_quitAppAction();
}
#endif


Do not forget to put int the .pro file the LIBS variable with the correct information to inform the linker! :D