1 /*************************************************************************** 2 * * 3 * This program is free software; you can redistribute it and/or modify * 4 * it under the terms of the GNU General Public License as published by * 5 * the Free Software Foundation; either version 3 of the License, or * 6 * (at your option) any later version. * 7 * * 8 ***************************************************************************/ 9 10 #pragma once 11 12 #include <QApplication> 13 #include <QEvent> 14 #include <QTimer> 15 #include <QSessionManager> 16 #include "WulforSettings.h" 17 #include "MainWindow.h" 18 #include "qtsingleapp/qtsinglecoreapplication.h" 19 #include <objc/objc.h> 20 #include <objc/message.h> 21 22 bool dockClickHandler(id self,SEL _cmd,...); 23 24 class EiskaltEventFilter: public QObject{ 25 Q_OBJECT 26 public: EiskaltEventFilter()27 EiskaltEventFilter(): counter(0), has_activity(true) { 28 timer.setInterval(60000); 29 30 connect(&timer, SIGNAL(timeout()), this, SLOT(tick())); 31 32 timer.start(); 33 } 34 ~EiskaltEventFilter()35 virtual ~EiskaltEventFilter() {} 36 37 protected: eventFilter(QObject * obj,QEvent * event)38 virtual bool eventFilter(QObject *obj, QEvent *event){ 39 switch (event->type()){ 40 case QEvent::MouseButtonPress: 41 case QEvent::MouseButtonRelease: 42 case QEvent::MouseButtonDblClick: 43 case QEvent::MouseMove: 44 case QEvent::KeyPress: 45 case QEvent::KeyRelease: 46 case QEvent::Wheel: 47 { 48 has_activity = true; 49 counter = 0; 50 51 break; 52 } 53 default: 54 { 55 has_activity = false; 56 57 break; 58 } 59 } 60 61 return QObject::eventFilter(obj, event); 62 } 63 64 private Q_SLOTS: tick()65 void tick(){ 66 if (!has_activity) 67 ++counter; 68 69 if (WBGET(WB_APP_AUTOAWAY_BY_TIMER)){ 70 int mins = WIGET(WI_APP_AUTOAWAY_INTERVAL); 71 72 if (!mins) 73 return; 74 75 int mins_done = (counter*timer.interval()/1000)/60; 76 77 if (mins <= mins_done) 78 dcpp::Util::setAway(true); 79 } 80 else if (has_activity && !dcpp::Util::getManualAway()) 81 dcpp::Util::setAway(false); 82 } 83 84 private: 85 QTimer timer; 86 int counter; 87 bool has_activity; 88 }; 89 90 class EiskaltApp: public QtSingleCoreApplication { 91 Q_OBJECT 92 public: EiskaltApp(int & argc,char * argv[],const QString & uniqKey)93 EiskaltApp(int &argc, char *argv[], const QString& uniqKey): QtSingleCoreApplication(argc, argv, uniqKey) 94 { 95 installEventFilter(&ef); 96 installMacHandlers(); 97 } 98 commitData(QSessionManager & manager)99 void commitData(QSessionManager& manager){ 100 if (MainWindow::getInstance()){ 101 MainWindow::getInstance()->beginExit(); 102 MainWindow::getInstance()->close(); 103 } 104 105 manager.release(); 106 } 107 saveState(QSessionManager &)108 void saveState(QSessionManager &){ /** Do nothing */ } 109 110 private: 111 EiskaltEventFilter ef; 112 installMacHandlers()113 void installMacHandlers(){ 114 objc_object* cls = (objc_object*)objc_getClass("NSApplication"); 115 SEL sharedApplication = sel_registerName("sharedApplication"); 116 objc_object* appInst = objc_msgSend(cls, sharedApplication); 117 118 if (appInst){ 119 objc_object* delegate = objc_msgSend(appInst, sel_registerName("delegate")); 120 objc_object* delClass = objc_msgSend(delegate, sel_registerName("class")); 121 const char* tst = class_getName(delClass->isa); 122 bool test = class_addMethod((objc_class*)delClass, 123 sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"), 124 (IMP)dockClickHandler,"B@:"); 125 if (!test){ 126 // failed to register handler... 127 } 128 } 129 } 130 }; 131