diff options
Diffstat (limited to 'src-qt5/core/lumina-desktop-unified/src-events')
5 files changed, 73 insertions, 703 deletions
diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LShortcutEvents.cpp b/src-qt5/core/lumina-desktop-unified/src-events/LShortcutEvents.cpp index b09a1a5b..3d50112c 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/LShortcutEvents.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-events/LShortcutEvents.cpp @@ -25,18 +25,9 @@ void LShortcutEvents::start(){ clearTimer->setSingleShot(true); connect(clearTimer, SIGNAL(timeout()), this, SLOT(clearKeys()) ); } - //Now connect this object to the global EFILTER object signals - connect(Lumina::EFILTER, SIGNAL(KeyPressed(WId, int)), this, SLOT(KeyPress(WId, int)) ); - connect(Lumina::EFILTER, SIGNAL(KeyReleased(WId, int)), this, SLOT(KeyRelease(WId, int)) ); - connect(Lumina::EFILTER, SIGNAL(MousePressed(WId, Lumina::MouseButton)), this, SLOT(MousePress(WId, Lumina::MouseButton)) ); - connect(Lumina::EFILTER, SIGNAL(MouseReleased(WId, Lumina::MouseButton)), this, SLOT(MouseRelease(WId, Lumina::MouseButton)) ); } void LShortcutEvents::stop(){ - disconnect(Lumina::EFILTER, SIGNAL(KeyPressed(WId, int)), this, SLOT(KeyPress(WId, int)) ); - disconnect(Lumina::EFILTER, SIGNAL(KeyReleased(WId, int)), this, SLOT(KeyRelease(WId, int)) ); - disconnect(Lumina::EFILTER, SIGNAL(MousePressed(WId, Lumina::MouseButton)), this, SLOT(MousePress(WId, Lumina::MouseButton)) ); - disconnect(Lumina::EFILTER, SIGNAL(MouseReleased(WId, Lumina::MouseButton)), this, SLOT(MouseRelease(WId, Lumina::MouseButton)) ); clearKeys(); } @@ -46,11 +37,11 @@ void LShortcutEvents::CheckKeySequence(WId win){ QString shortcut = keylistToString(); //Now see if there is a match for this shortcut // "strict" actions (operate even if a non-desktop window is active/focused) - QString action = Lumina::SETTINGS->value(DesktopSettings::Keys, "strict/"+shortcut, "").toString(); + QString action = DesktopSettings::instance()->value(DesktopSettings::Keys, "strict/"+shortcut, "").toString(); qDebug() << "Strict Action:" << "strict/"+shortcut << action; if(action.isEmpty() && win==0){ //"loose" actions (operating on the desktop or root window itself) - action = Lumina::SETTINGS->value(DesktopSettings::Keys, "desktop/"+shortcut, "").toString(); + action = DesktopSettings::instance()->value(DesktopSettings::Keys, "desktop/"+shortcut, "").toString(); qDebug() << "Desktop Action:" << "desktop/"+shortcut << action; } if(!action.isEmpty()){ @@ -59,42 +50,42 @@ void LShortcutEvents::CheckKeySequence(WId win){ } } -void LShortcutEvents::CheckMouseSequence(WId win, Lumina::MouseButton button, bool release){ - if(release && (button == Lumina::WheelUp || button == Lumina::WheelDown || button == Lumina::WheelLeft || button == Lumina::WheelRight)){ +void LShortcutEvents::CheckMouseSequence(WId win, NativeWindowSystem::MouseButton button, bool release){ + if(release && (button == NativeWindowSystem::WheelUp || button == NativeWindowSystem::WheelDown || button == NativeWindowSystem::WheelLeft || button == NativeWindowSystem::WheelRight)){ return; //skip mouse release events for wheel actions (always come in pairs of press/release) - }else if(keylist.isEmpty() || button == Lumina::NoButton){ return; } //Never overwrite mouse clicks themselves - just combinations with key presses + }else if(keylist.isEmpty() || button == NativeWindowSystem::NoButton){ return; } //Never overwrite mouse clicks themselves - just combinations with key presses //Get the keyboard modifiers QString shortcut = keylistToString(); //Add the mouse button to the shortcut switch(button){ - case Lumina::LeftButton: + case NativeWindowSystem::LeftButton: shortcut.append("+LeftMouse"); break; - case Lumina::RightButton: + case NativeWindowSystem::RightButton: shortcut.append("+RightMouse"); break; - case Lumina::MidButton: + case NativeWindowSystem::MidButton: shortcut.append("+MiddleMouse"); break; - case Lumina::BackButton: + case NativeWindowSystem::BackButton: shortcut.append("+BackMouse"); break; - case Lumina::ForwardButton: + case NativeWindowSystem::ForwardButton: shortcut.append("+ForwardMouse"); break; - case Lumina::TaskButton: + case NativeWindowSystem::TaskButton: shortcut.append("+TaskMouse"); break; - case Lumina::WheelUp: + case NativeWindowSystem::WheelUp: shortcut.append("+WheelUp"); break; - case Lumina::WheelDown: + case NativeWindowSystem::WheelDown: shortcut.append("+WheelDown"); break; - case Lumina::WheelLeft: + case NativeWindowSystem::WheelLeft: shortcut.append("+WheelLeft"); break; - case Lumina::WheelRight: + case NativeWindowSystem::WheelRight: shortcut.append("+WheelRight"); break; default: @@ -103,10 +94,10 @@ void LShortcutEvents::CheckMouseSequence(WId win, Lumina::MouseButton button, bo if(shortcut.isEmpty()){ return; } //Now see if there is a match for this shortcut // "strict" actions (operate even if a non-desktop window is active/focused) - QString action = Lumina::SETTINGS->value(DesktopSettings::Keys, "strict/"+shortcut, "").toString(); + QString action = DesktopSettings::instance()->value(DesktopSettings::Keys, "strict/"+shortcut, "").toString(); if(action.isEmpty() && win==0){ //"loose" actions (operating on the desktop or root window itself) - action = Lumina::SETTINGS->value(DesktopSettings::Keys, "desktop/"+shortcut, "").toString(); + action = DesktopSettings::instance()->value(DesktopSettings::Keys, "desktop/"+shortcut, "").toString(); } if(!action.isEmpty()){ //Found a valid action - go ahead and evaluate it @@ -115,23 +106,44 @@ void LShortcutEvents::CheckMouseSequence(WId win, Lumina::MouseButton button, bo } QString LShortcutEvents::keylistToString(){ + if(keylist.isEmpty()){ return ""; } QString shortcut; + QList<int> keys; int ckey = 0; for(int i=0; i<keylist.length(); i++){ - if(i>0){ shortcut.append("+"); } - shortcut.append( QString::number(keylist[i]) ); + if(i == keylist.length()-1){ ckey+=keylist[i]; } //always treat the last key as a non-modifier + else if(keylist[i] == Qt::Key_Control){ ckey+=Qt::CTRL; } //use the modifier form of the key + else if(keylist[i] == Qt::Key_Alt){ ckey += Qt::ALT; } + else if(keylist[i] == Qt::Key_Shift){ ckey += Qt::SHIFT; } + else if(keylist[i] == Qt::Key_Meta){ ckey += Qt::META; } + else{ ckey+= keylist[i]; keys << ckey; ckey = 0; } //non-modifier - need to finish current mod+key combo and start a new one + } + if(ckey!=0){ keys << ckey; } //add in the last one as well + if(keys.length() < 1){ return ""; } + QKeySequence seq; + switch(keys.length()){ + case 1: + seq = QKeySequence(keys[0]); break; + case 2: + seq = QKeySequence(keys[0], keys[1]); break; + case 3: + seq = QKeySequence(keys[0], keys[1], keys[2]); break; + default: + seq = QKeySequence(keys[0],keys[1], keys[2], keys[3]); break; } /*qDebug() << "KeyList to String:"; - qDebug() << " keys:" << keylist; - qDebug() << " string:" << shortcut;*/ - return shortcut; + qDebug() << " keys:" << seq; + qDebug() << " string:" << seq.toString();*/ + return seq.toString(); } void LShortcutEvents::evaluateShortcutAction(QString action){ qDebug() << "Found Shortcut Action:" << action; evaluated = true; - if(action.startsWith("Exec=")){ - emit LaunchApplication(action.section("=",1,-1)); + if(action.startsWith("Exec:")){ + emit LaunchApplication(action.section(":",1,-1)); return; + }else if(action.startsWith("Launch:")){ + emit LaunchStandardApplication(action.section(":",1,-1)); } //Specific Internal actions action = action.toLower(); @@ -140,13 +152,14 @@ void LShortcutEvents::evaluateShortcutAction(QString action){ else if(action=="reboot"){ emit StartReboot(); } else if(action=="shutdown"){ emit StartShutdown(); } else if(action=="show_leave_options"){ emit OpenLeaveDialog(); } + else if(action=="lockscreen"){ emit LockSession(); } } // === PUBLIC SLOTS === -void LShortcutEvents::KeyPress(WId window, int key){ +void LShortcutEvents::KeyPress(WId window, Qt::Key key){ if(window!=WIN){ keylist.clear(); WIN = window; } - if(!keylist.contains(key)){ + /*if(!keylist.contains(key)){ //Put it in the list in ascending order bool found = false; for(int i=0; i<keylist.length() && !found; i++){ @@ -154,28 +167,35 @@ void LShortcutEvents::KeyPress(WId window, int key){ } if(!found){ keylist << key; } evaluated = false; + }*/ + if(!keylist.isEmpty()){ + if( keylist.last()!=key ){ keylist << key; } + }else{ + keylist << key; } //Evaluate the key sequence only when the first one is released - clearTimer->start(); //will "restart" if already running + clearTimer->start(); //will "restart" if already running } -void LShortcutEvents::KeyRelease(WId window, int key){ +void LShortcutEvents::KeyRelease(WId window, Qt::Key key){ if(window!=WIN){ keylist.clear(); return; } if(!evaluated){ CheckKeySequence(WIN); } //run this "before" removing the key from the list - keylist.removeAll(key); - clearTimer->start(); //will "restart" if already running + for(int i=keylist.length()-1; i>=0; i--){ + if(keylist[i] == key){ keylist.removeAt(i); break; } + } + clearTimer->start(); //will "restart" if already running } -void LShortcutEvents::MousePress(WId window, Lumina::MouseButton button){ +void LShortcutEvents::MousePress(WId window, NativeWindowSystem::MouseButton button){ //We do not provide shortcuts for combinations of mouse buttons - just mouse+keyboard combinations CheckMouseSequence(window, button, false); - clearTimer->start(); //will "restart" if already running + clearTimer->start(); //will "restart" if already running } -void LShortcutEvents::MouseRelease(WId window, Lumina::MouseButton button){ +void LShortcutEvents::MouseRelease(WId window, NativeWindowSystem::MouseButton button){ //We do not provide shortcuts for combinations of mouse buttons - just mouse+keyboard combinations CheckMouseSequence(window, button, true); - clearTimer->start(); //will "restart" if already running + clearTimer->start(); //will "restart" if already running } void LShortcutEvents::clearKeys(){ diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LShortcutEvents.h b/src-qt5/core/lumina-desktop-unified/src-events/LShortcutEvents.h index d1c3b4e0..4560cb1f 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/LShortcutEvents.h +++ b/src-qt5/core/lumina-desktop-unified/src-events/LShortcutEvents.h @@ -22,22 +22,22 @@ public: void stop(); private: - QList<int> keylist; //keys currently held down (NOTE: QKeySequence has a max of 4 keys for combinations) + QList< Qt::Key > keylist; //keys currently held down WId WIN; //current window being acted on by the keys QTimer *clearTimer; //used to clear the internal keylist every once in a while if no events come in. bool evaluated; //Actual check functions void CheckKeySequence(WId win); - void CheckMouseSequence(WId win, Lumina::MouseButton, bool release); + void CheckMouseSequence(WId win, NativeWindowSystem::MouseButton, bool release); QString keylistToString(); void evaluateShortcutAction(QString action); public slots: - void KeyPress(WId window, int key); - void KeyRelease(WId window, int key); - void MousePress(WId window, Lumina::MouseButton); - void MouseRelease(WId window, Lumina::MouseButton); + void KeyPress(WId window, Qt::Key key); + void KeyRelease(WId window, Qt::Key key); + void MousePress(WId window, NativeWindowSystem::MouseButton); + void MouseRelease(WId window, NativeWindowSystem::MouseButton); void clearKeys(); signals: @@ -50,7 +50,7 @@ signals: // Session Options void ChangeWorkspace(int); // +/- 1 from current void LockSession(); - + //Active Window Options void ActiveWindowMoveToWorkspace(int); //number of workspace void ActiveWindowTakeToWorkspace(int); //number of workspace @@ -66,6 +66,7 @@ signals: //General Utility Launch void LaunchApplication(QString exec); + void LaunchStandardApplication(QString app); //standard app like "terminal", "browser", "email", "settings", etc.. }; diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp deleted file mode 100644 index 7031f3df..00000000 --- a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp +++ /dev/null @@ -1,500 +0,0 @@ -//=========================================== -// Lumina-desktop source code -// Copyright (c) 2015-2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -#include "LXcbEventFilter.h" - -#include <xcb/xcb_aux.h> -#include <xcb/damage.h> - -//================================================== -// NOTE: All the XCB interactions and atoms are accessed via: -// obj->XCB->EWMH.(atom name) -// obj->XCB->(do something) -//================================================== -#include "global-objects.h" - -//SYSTEM TRAY STANDARD DEFINITIONS -#define SYSTEM_TRAY_REQUEST_DOCK 0 -#define SYSTEM_TRAY_BEGIN_MESSAGE 1 -#define SYSTEM_TRAY_CANCEL_MESSAGE 2 - -#include <xcb/xcb_keysyms.h> - -#define DEBUG 0 - -// Also keep the root window/screen around for use in the filters -namespace L_XCB{ - xcb_screen_t *root_screen; - xcb_window_t root; -} - -//Constructor for the Event Filter wrapper -EventFilter::EventFilter() : QObject(){ - XCB = new LXCB(); - EF = new XCBEventFilter(this); - L_XCB::root_screen = xcb_aux_get_screen(QX11Info::connection(), QX11Info::appScreen()); - L_XCB::root = L_XCB::root_screen->root; - WMFlag = 0; -} - -void EventFilter::start(){ - if(DEBUG){ qDebug() << " - Install event filter..."; } - QCoreApplication::instance()->installNativeEventFilter(EF); - if(DEBUG){ qDebug() << " - Run request check..."; } - if(!XCB->setupEventsForRoot()){ - qCritical() << "[ERROR] Unable to setup WM event retrieval. Is another WM running?"; - exit(1); - } - if(DEBUG){ qDebug() << " - Create WM ID Window"; } - WMFlag = XCB->WM_CreateWindow(); - XCB->setupEventsForRoot(WMFlag); - XCB->WM_Set_Supporting_WM(WMFlag); - - XCB->WM_Set_Root_Supported(); //announce all the various options that the WM supports - static_cast<XCBEventFilter*>(EF)->startSystemTray(); - - QCoreApplication::instance()->flush(); -} - -void EventFilter::stop(){ - static_cast<XCBEventFilter*>(EF)->stopSystemTray(); -} - -//Session Interaction/Information -QList<WId> EventFilter::currentTrayApps(){ - return static_cast<XCBEventFilter*>(EF)->trayApps(); -} - -unsigned int EventFilter::currentWorkspace(){ -return XCB->CurrentWorkspace(); -} - -QList<NativeWindow*> EventFilter::currentWindows(){ - return static_cast<XCBEventFilter*>(EF)->windowList(); -} - -// === PUBLIC SLOTS === -void EventFilter::RegisterVirtualRoot(WId id){ - XCB->WM_Set_Virtual_Roots( QList<WId>() << id ); -} - -void EventFilter::TryCloseWindow(WId id){ - XCB->WM_CloseWindow(id, false); //do not force close -} - -void EventFilter::TryActivateWindow(WId id){ - XCB->WM_Set_Active_Window(id); -} -//============================= -// XCBEventFilter Class -//============================= - -//Constructor for the XCB event filter -XCBEventFilter::XCBEventFilter(EventFilter *parent) : QAbstractNativeEventFilter(){ - obj = parent; - SystemTrayID = 0; - TrayDmgID = 0; - InitAtoms(); -} - -void XCBEventFilter::InitAtoms(){ - //Initialize any special atoms that we need to save/use regularly - //NOTE: All the EWMH atoms are already saved globally in obj->XCB->EWMH - WinNotifyAtoms.clear(); - WinNotifyAtoms << obj->XCB->EWMH._NET_WM_NAME \ - << obj->XCB->EWMH._NET_WM_VISIBLE_NAME \ - << obj->XCB->EWMH._NET_WM_ICON_NAME \ - << obj->XCB->EWMH._NET_WM_VISIBLE_ICON_NAME \ - << obj->XCB->EWMH._NET_WM_ICON \ - << obj->XCB->EWMH._NET_WM_ICON_GEOMETRY; - - SysNotifyAtoms.clear(); - SysNotifyAtoms << obj->XCB->EWMH._NET_CLIENT_LIST \ - << obj->XCB->EWMH._NET_CLIENT_LIST_STACKING \ - << obj->XCB->EWMH._NET_CURRENT_DESKTOP \ - << obj->XCB->EWMH._NET_WM_STATE \ - << obj->XCB->EWMH._NET_ACTIVE_WINDOW \ - << obj->XCB->EWMH._NET_WM_ICON \ - << obj->XCB->EWMH._NET_WM_ICON_GEOMETRY; - - //_NET_SYSTEM_TRAY_OPCODE - xcb_intern_atom_cookie_t cookie = xcb_intern_atom(QX11Info::connection(), 0, 23,"_NET_SYSTEM_TRAY_OPCODE"); - xcb_intern_atom_reply_t *r = xcb_intern_atom_reply(QX11Info::connection(), cookie, NULL); - if(r){ - _NET_SYSTEM_TRAY_OPCODE = r->atom; - free(r); - } -} - -//This function format taken directly from the Qt5.3 documentation -bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *){ - //if(stopping){ return false; } //don't do any parsing - //qDebug() << "New Event"; - bool stopevent = false; - if(eventType=="xcb_generic_event_t"){ - //Convert to known event type (for X11 systems) - xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message); - //Now parse the event and emit signals as necessary - switch( ev->response_type & ~0x80){ -//============================== -// INTERACTIVITY EVENTS -//============================== - case XCB_KEY_PRESS: - //This is a keyboard key press - //qDebug() << "Key Press Event"; - stopevent = BlockInputEvent( ((xcb_key_press_event_t *) ev)->root ); //use the main "root" window - not the child widget - if(!stopevent){ obj->emit KeyPressed( InputWindow(((xcb_key_press_event_t *) ev)->root), ((xcb_key_press_event_t *) ev)->detail ); } - break; - case XCB_KEY_RELEASE: - //This is a keyboard key release - //qDebug() << "Key Release Event"; - stopevent = BlockInputEvent( ((xcb_key_release_event_t *) ev)->root ); //use the main "root" window - not the child widget - if(!stopevent){ obj->emit KeyReleased( InputWindow(((xcb_key_release_event_t *) ev)->root), ((xcb_key_release_event_t *) ev)->detail ); } - break; - case XCB_BUTTON_PRESS: - //This is a mouse button press - qDebug() << "Button Press Event"; - stopevent = BlockInputEvent( ((xcb_button_press_event_t *) ev)->root ); //use the main "root" window - not the child widget - if(!stopevent){ - //Activate the window right now if needed - obj->emit MousePressed( InputWindow(((xcb_button_press_event_t *) ev)->root), MouseKey(((xcb_key_press_event_t *) ev)->detail) ); - if(obj->XCB->WM_Get_Active_Window()!=((xcb_button_press_event_t *) ev)->root){ - obj->XCB->WM_Set_Active_Window( ((xcb_button_press_event_t *) ev)->root); - } - } - break; - case XCB_BUTTON_RELEASE: - //This is a mouse button release - qDebug() << "Button Release Event"; - //xcb_button_release_event_t *tmp = (xcb_button_release_event_t *)ev; - stopevent = BlockInputEvent( ((xcb_button_release_event_t *) ev)->root ); //use the main "root" window - not the child widget - if(!stopevent){ obj->emit MouseReleased( InputWindow(((xcb_button_release_event_t *) ev)->root), MouseKey(((xcb_key_press_event_t *) ev)->detail) ); } - break; - case XCB_MOTION_NOTIFY: - //This is a mouse movement event - //qDebug() << "Motion Notify Event"; - stopevent = BlockInputEvent( ((xcb_motion_notify_event_t *) ev)->root ); //use the main "root" window - not the child widget); - break; - case XCB_ENTER_NOTIFY: - //This is a mouse movement event when mouse goes over a new window - //qDebug() << "Enter Notify Event"; - stopevent = BlockInputEvent( ((xcb_enter_notify_event_t *) ev)->root ); - break; - case XCB_LEAVE_NOTIFY: - //This is a mouse movement event when mouse goes leaves a window - //qDebug() << "Leave Notify Event"; - stopevent = BlockInputEvent(); - break; -//============================== - case XCB_EXPOSE: - //qDebug() << "Expose Notify Event:"; - //qDebug() << " - Given Window:" << ((xcb_property_notify_event_t*)ev)->window; - break; -//============================== - case XCB_MAP_NOTIFY: - //qDebug() << "Window Map Event:" << ((xcb_map_notify_event_t *)ev)->window; - if(Lumina::SS->isLocked()){ waitingToShow << ((xcb_map_notify_event_t *)ev)->window ; } - else{ - for(int i=0; i<windows.length(); i++){ - if(windows[i]->id() == ((xcb_map_notify_event_t *)ev)->window){ windows[i]->setProperty(NativeWindow::Visible, true); break; } - } - } - break; //This is just a notification that a window was mapped - nothing needs to change here - case XCB_MAP_REQUEST: - //qDebug() << "Window Map Request Event"; - SetupNewWindow( ((xcb_map_request_event_t *) ev) ); - break; -//============================== - case XCB_CREATE_NOTIFY: - //qDebug() << "Window Create Event"; - break; -//============================== - case XCB_UNMAP_NOTIFY: - //qDebug() << "Window Unmap Event:" << ((xcb_unmap_notify_event_t *)ev)->window; - if(waitingToShow.contains(((xcb_unmap_notify_event_t *)ev)->window)){ waitingToShow.removeAll(((xcb_unmap_notify_event_t *)ev)->window); } - for(int i=0; i<windows.length(); i++){ - if(windows[i]->id() == ((xcb_unmap_notify_event_t *)ev)->window){ windows[i]->setProperty(NativeWindow::Visible, false); break; } - } - break; -//============================== - case XCB_DESTROY_NOTIFY: - //qDebug() << "Window Closed Event:" << ((xcb_destroy_notify_event_t *)ev)->window; - if( !rmTrayApp( ((xcb_destroy_notify_event_t *) ev)->window ) ){ - //qDebug() <<" - Non-tray window"; - for(int i=0; i<windows.length(); i++){ - if(windows[i]->id() == ((xcb_destroy_notify_event_t *)ev)->window){ - windows[i]->emit WindowClosed(windows[i]->id()); - QTimer::singleShot(500, windows.takeAt(i), SLOT(deleteLater()) ); //give a few moments first, then clean up the object - break; - } - } - } - break; -//============================== - case XCB_FOCUS_IN: - //qDebug() << "Focus In Event:"; - break; -//============================== - case XCB_FOCUS_OUT: - //qDebug() << "Focus Out Event:"; - break; -//============================== - case XCB_PROPERTY_NOTIFY: - //qDebug() << "Property Notify Event:"; - ParsePropertyEvent((xcb_property_notify_event_t*)ev); - break; -//============================== - case XCB_CLIENT_MESSAGE: - //qDebug() << "Client Message Event"; - //qDebug() << " - Given Window:" << ((xcb_client_message_event_t*)ev)->window; - if( ((xcb_client_message_event_t*)ev)->type == _NET_SYSTEM_TRAY_OPCODE && ((xcb_client_message_event_t*)ev)->format == 32){ - //data32[0] is timestamp, [1] is opcode, [2] is window handle - if(SYSTEM_TRAY_REQUEST_DOCK == ((xcb_client_message_event_t*)ev)->data.data32[1]){ - addTrayApp( ((xcb_client_message_event_t*)ev)->data.data32[2] ); - } - //Ignore the System Tray messages at the moment - - } - break; -//============================== - case XCB_CONFIGURE_NOTIFY: - //qDebug() << "Configure Notify Event"; - break; -//============================== - case XCB_CONFIGURE_REQUEST: - //qDebug() << "Configure Request Event"; - break; -//============================== - case XCB_SELECTION_CLEAR: - //qDebug() << "Selection Clear Event"; - break; -//============================== - case 85: //not sure what event this is - but it seems to come up very often (just hide the notice) - case 0: - case XCB_GE_GENERIC: - break; //generic event - don't do anything special - default: - //if( (ev->response_type & ~0x80)==TrayDmgID){ - checkDamageID( ((xcb_damage_notify_event_t*)ev)->drawable ); - //}else{ - qDebug() << "Default Event:" << (ev->response_type & ~0x80); - //} -//============================== - } - } - return false; - //never stop event handling (this will not impact the X events themselves - just the internal screensaver/WM/widgets) -} - -//System Tray Functions -QList<WId> XCBEventFilter::trayApps(){ - //return the list of all current tray apps - //Check the validity of all the current tray apps (make sure nothing closed erratically) - for(int i=0; i<RunningTrayApps.length(); i++){ - if(obj->XCB->WindowClass(RunningTrayApps[i]).isEmpty()){ - obj->emit Tray_AppClosed(RunningTrayApps.takeAt(i) ); - i--; - } - } - return RunningTrayApps; -} - -bool XCBEventFilter::startSystemTray(){ - if(SystemTrayID != 0){ return true; } //already started - RunningTrayApps.clear(); //nothing running yet - SystemTrayID = obj->XCB->startSystemTray(0); - if(SystemTrayID!=0){ - obj->XCB->SelectInput(SystemTrayID); //make sure TrayID events get forwarded here - TrayDmgID = obj->XCB->GenerateDamageID(SystemTrayID); - qDebug() << "System Tray Started Successfully"; - if(DEBUG){ qDebug() << " - System Tray Flags:" << TrayDmgID; } - } - return (SystemTrayID!=0); -} - -bool XCBEventFilter::stopSystemTray(){ - if(SystemTrayID==0){ return true; } //already stopped - qDebug() << "Stopping system tray..."; - //Close all the running Tray Apps - QList<WId> tmpApps = RunningTrayApps; - //RunningTrayApps.clear(); //clear this ahead of time so tray's do not attempt to re-access the apps - //Close all the running tray apps - for(int i=0; i<tmpApps.length(); i++){ - qDebug() << " - Stopping tray app:" << obj->XCB->WindowClass(tmpApps[i]); - //Tray apps are special and closing the window does not close the app - obj->XCB->KillClient(tmpApps[i]); - } - //Now close down the tray backend - obj->XCB->closeSystemTray(SystemTrayID); - SystemTrayID = 0; - TrayDmgID = 0; - return true; -} - -QList<NativeWindow*> XCBEventFilter::windowList(){ - return windows; -} - -//========= -// PRIVATE -//========= -bool XCBEventFilter::BlockInputEvent(WId){ - //Checks the current state of the WM and sets the stop flag as needed - // - Always let the screensaver know about the event first (need to reset timers and such) - obj->emit NewInputEvent(); - // - Check the state of the screensaver - if(Lumina::SS->isLocked()){ qDebug() << "SS Locked"; return true; } - // - Check the state of any fullscreen apps - /*else if( win!=0 && !obj->FS_WINS.isEmpty()){ - if(!obj->FS_WINS.contains(win) ){ - //If this event is for an app underneath a fullscreen window - stop it - if(obj->FS_WINS.length() == QApplication::desktop()->screenCount()){ qDebug() << "Screens Covered"; return true; } //all screens covered right now - } - }*/ - return false; -} - -WId XCBEventFilter::InputWindow(WId win){ - //check window and see if it is a desktop/root window (return 0) or an external app window - if(win == L_XCB::root){ return 0; } - QString cl = obj->XCB->WindowClass(win); - qDebug() << "Got Input Event on window:" << cl; - if(cl.toLower()=="lumina-desktop"){ return 0; } - return win; //external app window -} - -Lumina::MouseButton XCBEventFilter::MouseKey(int keycode){ - switch(keycode){ - case 1: - return Lumina::LeftButton; - case 3: - return Lumina::RightButton; - case 2: - return Lumina::MidButton; - case 4: - return Lumina::WheelUp; - case 5: - return Lumina::WheelDown; - case 6: - return Lumina::WheelLeft; - case 7: - return Lumina::WheelRight; - case 8: - return Lumina::BackButton; //Not sure if this is correct yet (1/27/17) - case 9: - return Lumina::ForwardButton; //Not sure if this is correct yet (1/27/17) - default: - return Lumina::NoButton; - } -} - -//System Tray functions -void XCBEventFilter::addTrayApp(WId win){ - if(SystemTrayID==0){ return; } - if(RunningTrayApps.contains(win)){ return; } //already managed - qDebug() << "Session Tray: Window Added" << obj->XCB->WindowClass(win); - RunningTrayApps << win; - if(DEBUG){ qDebug() << "Tray List Changed"; } - obj->emit Tray_AppAdded(win); -} - -bool XCBEventFilter::rmTrayApp(WId win){ - //returns "true" if the tray app was found and removed - if(SystemTrayID==0){ return false; } - for(int i=0; i<RunningTrayApps.length(); i++){ - if(win==RunningTrayApps[i]){ - qDebug() << "Session Tray: Window Removed"; - RunningTrayApps.removeAt(i); - obj->emit Tray_AppClosed(win); - return true; - } - } - return false; -} - -void XCBEventFilter::checkDamageID(WId id){ - if(RunningTrayApps.contains(id)){ - obj->emit Tray_AppUpdated(id); - }else{ - //Could check for window damage ID's - but we should not need this - } -} - -// WINDOW HANDLING FUNCTIONS -void XCBEventFilter::SetupNewWindow(xcb_map_request_event_t *ev){ - WId win = ev->window; - - bool ok = obj->XCB->WM_ManageWindow(win, true); - //Quick check if this is a transient window if we could not manage it directly - if(!ok){ - WId tran = obj->XCB->WM_ICCCM_GetTransientFor(win); - if(tran!=win && tran!=0){ - win = tran; - ok = obj->XCB->WM_ManageWindow(win); - } - } - qDebug() << "New Window:" << win << obj->XCB->WM_ICCCM_GetClass(win) << " Managed:" << ok; - obj->XCB->WM_Set_Active_Window(win); - //Determing the requested geometry/location/management within the event, - NativeWindow *nwin = new NativeWindow(win); - QObject::connect(nwin, SIGNAL(RequestClose(WId)), obj, SLOT(TryCloseWindow(WId)) ); - QObject::connect(nwin, SIGNAL(RequestActivate(WId)), obj, SLOT(TryActivateWindow(WId)) ); - windows << nwin; - bool show_now = !Lumina::SS->isLocked(); - if(!show_now){ waitingToShow << win; } //add to the list to get set visible later - //populate the native window settings as they are right now - nwin->setProperty(NativeWindow::Active, true); - nwin->setProperty(NativeWindow::Visible, show_now); - nwin->setProperty(NativeWindow::Workspace, obj->XCB->CurrentWorkspace()); - icccm_size_hints hints = obj->XCB->WM_ICCCM_GetNormalHints(win); - if(!hints.isValid()){ hints = obj->XCB->WM_ICCCM_GetSizeHints(win); } - if(hints.validMinSize()){ nwin->setProperty(NativeWindow::MinSize, QSize(hints.min_width,hints.min_height)); } - if(hints.validMaxSize()){ nwin->setProperty(NativeWindow::MaxSize, QSize(hints.max_width,hints.max_height)); } - if(hints.validBaseSize()){ nwin->setProperty(NativeWindow::Size, QSize(hints.base_width,hints.base_height)); } - else if(hints.validSize()){ nwin->setProperty(NativeWindow::Size, QSize(hints.width, hints.height)); } - nwin->setProperty(NativeWindow::Icon, obj->XCB->WM_Get_Icon(win)); - QString title = obj->XCB->WM_Get_Name(win); - if(title.isEmpty()){ title = obj->XCB->WM_Get_Visible_Name(win); } - if(title.isEmpty()){ title = obj->XCB->WM_ICCCM_GetName(win); } - nwin->setProperty(NativeWindow::Title, title); - title = obj->XCB->WM_Get_Icon_Name(win); - if(title.isEmpty()){ title = obj->XCB->WM_Get_Visible_Icon_Name(win); } - if(title.isEmpty()){ title = obj->XCB->WM_ICCCM_GetIconName(win); } - nwin->setProperty(NativeWindow::ShortTitle, title); - - obj->emit WindowCreated(nwin); -} - -void XCBEventFilter::ParsePropertyEvent(xcb_property_notify_event_t *ev){ - //First find the NativeWindow associated with the event - NativeWindow *nwin = 0; - for(int i=0; i<windows.length() && nwin==0; i++){ - if(windows[i]->id() == ev->window){ nwin = windows[i]; } - } - if(nwin==0){ return; } //unmanaged window - ignore this event - qDebug() << "Got Property Event:" << ev->window << ev->atom; - //Now determine which properties are getting changed, and update the native window as appropriate - if(ev->atom == obj->XCB->EWMH._NET_WM_NAME){ - qDebug() << " - Found _NET_WM_NAME atom"; - nwin->setProperty(NativeWindow::Title, obj->XCB->WM_Get_Name(nwin->id())); - }else if(ev->atom == obj->XCB->EWMH._NET_WM_ICON){ - qDebug() << " - Found _NET_WM_ICON atom"; - nwin->setProperty(NativeWindow::Icon, obj->XCB->WM_Get_Icon(nwin->id())); - }else if(ev->atom == obj->XCB->EWMH._NET_WM_ICON_NAME){ - qDebug() << " - Found _NET_WM_ICON_NAME atom"; - nwin->setProperty(NativeWindow::ShortTitle, obj->XCB->WM_Get_Icon_Name(nwin->id())); - }else if(ev->atom == obj->XCB->EWMH._NET_WM_DESKTOP){ - qDebug() << " - Found _NET_WM_DESKTOP atom"; - nwin->setProperty(NativeWindow::Workspace, obj->XCB->WM_Get_Desktop(nwin->id())); - }else if(ev->atom == obj->XCB->EWMH._NET_WM_WINDOW_TYPE ){ - qDebug() << " - Found _NET_WM_WINDOW_TYPE atom"; - - }else if( ev->atom == obj->XCB->EWMH._NET_WM_STATE){ - qDebug() << " - Found _NET_WM_STATE atom"; - - } - -} diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h deleted file mode 100644 index 9f2530e8..00000000 --- a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h +++ /dev/null @@ -1,151 +0,0 @@ -//=========================================== -// Lumina-DE source code -// Copyright (c) 2012-2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -// This class provides the XCB event handling/registrations that are needed -//=========================================== -#ifndef _LUMINA_DESKTOP_XCB_FILTER_H -#define _LUMINA_DESKTOP_XCB_FILTER_H - -#include "global-includes.h" - - -/* -List of XCB response types (since almost impossible to find good docs on XCB) -switch (xcb_generic_event_t*->response_type & ~0x80) -case values: -XCB_KEY_[PRESS | RELEASE] -XCB_BUTTON_[PRESS | RELEASE] -XCB_MOTION_NOTIFY -XCB_ENTER_NOTIFY -XCB_LEAVE_NOTIFY -XCB_FOCUS_[IN | OUT] -XCB_KEYMAP_NOTIFY -XCB_EXPOSE -XCB_GRAPHICS_EXPOSURE -XCB_VISIBILITY_NOTIFY -XCB_CREATE_NOTIFY -XCB_DESTROY_NOTIFY -XCB_UNMAP_NOTIFY -XCB_MAP_[NOTIFY | REQUEST] -XCB_REPARENT_NOTIFY -XCB_CONFIGURE_[NOTIFY | REQUEST] -XCB_GRAVITY_NOTIFY -XCB_RESIZE_REQUEST -XCB_CIRCULATE_[NOTIFY | REQUEST] -XCB_PROPERTY_NOTIFY -XCB_SELECTION_[CLEAR | REQUEST | NOTIFY] -XCB_COLORMAP_NOTIFY -XCB_CLIENT_MESSAGE -*/ - - -class EventFilter : public QObject{ - Q_OBJECT -private: - QAbstractNativeEventFilter* EF; - WId WMFlag; //used to flag a running WM process - -public: - EventFilter(); - ~EventFilter(){} - - void start(); - void stop(); - - //Public System Tray Functions - QList<WId> currentTrayApps(); - - //Public Session Interaction Functions - unsigned int currentWorkspace(); - - //Public Window Management Lists - QList<NativeWindow*> currentWindows(); //always returned in creation-order (oldest first) - - //Variables/Functions needed by the XCBEventFilter class only (not really needed by anything else) - LXCB *XCB; //used to interact with the X11 graphics subsystem - -public slots: - void RegisterVirtualRoot(WId); - void TryCloseWindow(WId); - void TryActivateWindow(WId); - -signals: - void NewInputEvent(); - void WindowCreated(NativeWindow*); - - // Session Signals - void WorkspaceChanged(unsigned int); - - // System Tray Signals - void Tray_AppAdded(WId); //new tray app registered - void Tray_AppClosed(WId); //tray app de-registered - void Tray_AppUpdated(WId); //tray app appearance changed (damage event) - // Shortcut Signals - void KeyPressed(WId, int); - void KeyReleased(WId, int); - void MousePressed(WId, Lumina::MouseButton); - void MouseReleased(WId, Lumina::MouseButton); -}; - -class XCBEventFilter : public QAbstractNativeEventFilter{ -public: - XCBEventFilter(EventFilter *parent); - ~XCBEventFilter(){} - - virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *); - - //System Tray Functions - QList<WId> trayApps(); //return the list of all current tray apps - bool startSystemTray(); - bool stopSystemTray(); - - //Window List Functions - QList<NativeWindow*> windowList(); - -private: - EventFilter *obj; - QList<xcb_atom_t> WinNotifyAtoms, SysNotifyAtoms; - xcb_atom_t _NET_SYSTEM_TRAY_OPCODE; - void InitAtoms(); - - bool BlockInputEvent(WId win = 0); //Checks the current state of the system to see if the event should be stopped - WId InputWindow(WId win = 0); //Checks the window ID and determines if this is an external window or returns 0 (for desktop/root windows) - Lumina::MouseButton MouseKey(int keycode); //convert the keycode into the mouse button code - - - //System Tray Variables - WId SystemTrayID; - int TrayDmgID; - QList<WId> RunningTrayApps; - //System Tray functions - void addTrayApp(WId); - bool rmTrayApp(WId); //returns "true" if the tray app was found and removed - void checkDamageID(WId); - - //Window List Variables - QList<NativeWindow*> windows; - QList<WId> waitingToShow; - - //Longer Event handling functions - void SetupNewWindow(xcb_map_request_event_t *ev); - - //bool ParseKeyPressEvent(); - //bool ParseKeyReleaseEvent(); - //bool ParseButtonPressEvent(); - //bool ParseButtonReleaseEvent(); - //bool ParseMotionEvent(); - void ParsePropertyEvent(xcb_property_notify_event_t *ev); - //bool ParseClientMessageEvent(); - //bool ParseDestroyEvent(); - //bool ParseConfigureEvent(); - //bool ParseKeySelectionClearEvent(); - - - - -}; - -#endif diff --git a/src-qt5/core/lumina-desktop-unified/src-events/events.pri b/src-qt5/core/lumina-desktop-unified/src-events/events.pri index 9eec91ca..48d500ed 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/events.pri +++ b/src-qt5/core/lumina-desktop-unified/src-events/events.pri @@ -1,6 +1,6 @@ -SOURCES *= $${PWD}/LXcbEventFilter.cpp +#SOURCES *= $${PWD}/LXcbEventFilter.cpp -HEADERS *= $${PWD}/LXcbEventFilter.h +#HEADERS *= $${PWD}/LXcbEventFilter.h #Shortcut event files SOURCES *= $${PWD}/LShortcutEvents.cpp |