diff --git a/README.references.txt b/README.references.txt index f01f2cf..3f2a55c 100644 --- a/README.references.txt +++ b/README.references.txt @@ -8,18 +8,26 @@ c# remove 3rd party application from taskbar https://stackoverflow.com/questions/10514882/c-sharp-remove-3rd-party-application-from-taskbar - Close window - https://docs.microsoft.com/en-us/windows/win32/learnwin32/closing-the-window +Block close button +https://devblogs.microsoft.com/oldnewthing/20100604-00/?p=13803 + + Get processes - (EnumProcesses function) https://www.qtcentre.org/threads/46145-Get-All-Running-Process-Win32 +Get (Pid) and PPid +https://stackoverflow.com/questions/185254/how-can-a-win32-process-get-the-pid-of-its-parent +https://stackoverflow.com/questions/18401572/c-how-to-fetch-parent-process-id + +https://www.codeproject.com/Articles/9893/Get-Parent-Process-PID + + X11 ========================================== diff --git a/app/SysTray-X/windowctrl-unix.cpp b/app/SysTray-X/windowctrl-unix.cpp index 66b082a..81ee9cb 100644 --- a/app/SysTray-X/windowctrl-unix.cpp +++ b/app/SysTray-X/windowctrl-unix.cpp @@ -15,6 +15,12 @@ */ WindowCtrlUnix::WindowCtrlUnix( QObject *parent ) : QObject( parent ) { + /* + * Initialize + */ + m_tb_window = 0; + m_tb_windows = QList< quint64 >(); + /* * Get the base display and window */ @@ -67,6 +73,49 @@ bool WindowCtrlUnix::findWindow( const QString& title ) } +/* + * Find a window by PID + */ +void WindowCtrlUnix::findWindow( qint64 pid ) +{ + QList< WindowItem > windows = listXWindows( m_display, m_root_window ); + + // Get the PID property atom. + Atom atom_PID = XInternAtom( m_display, "_NET_WM_PID", True ); + if( atom_PID == None ) + { + emit signalConsole( QString( "No such atom _NET_WM_PID" ) ); + } + + m_tb_window = 0; + foreach( WindowItem win, windows ) + { + Atom type; + int format; + unsigned long nItems; + unsigned long bytesAfter; + + unsigned char* propPID = nullptr; + if( Success == XGetWindowProperty( m_display, win.window, atom_PID, 0, 1, False, XA_CARDINAL, + &type, &format, &nItems, &bytesAfter, &propPID ) ) + { + if( propPID != nullptr ) + { + if( pid == *((reinterpret_cast( propPID ) ) ) ) + { + m_tb_window = win.window; + + XFree( propPID ); + return; + } + + XFree( propPID ); + } + } + } +} + + /* * Display window atoms */ @@ -83,80 +132,99 @@ void WindowCtrlUnix::displayWindowElements( const QString& title ) XFree( name ); if( win_name.contains( title, Qt::CaseInsensitive ) ) { + emit signalConsole( QString( "Found: Level %1, XID %2, Name %3" ).arg( win.level ).arg( win.window ).arg( win_name ) ); - QString name = atomName( m_display, win.window ); - emit signalConsole( QString( "Atom name: %1" ).arg( name ) ); - - QStringList types = atomWindowType( m_display, win.window ); - foreach( QString type, types ) - { - emit signalConsole( QString( "Atom type: %1" ).arg( type ) ); - } - - QStringList states = atomState( m_display, win.window ); - - bool max_vert = false; - bool max_horz = false; - bool hidden = false; - - foreach( QString state, states ) - { - emit signalConsole( QString( "Atom state: %1" ).arg( state ) ); - - int state_code = WindowStates.indexOf( state ) ; - - switch( state_code ) - { - case STATE_MAXIMIZED_VERT: - { - max_vert = true; - break; - } - - case STATE_MAXIMIZED_HORZ: - { - max_horz = true; - break; - } - - case STATE_HIDDEN: - { - hidden = true; - break; - } - } - } - - if( states.length() > 0 ) - { - if( hidden ) - { - emit signalConsole( "Window State: Hidden" ); - } - else - if( max_vert && max_horz ) - { - emit signalConsole( "Window State: Maximize" ); - } - else - { - emit signalConsole( "Window State: Normal" ); - } - } - else - { - emit signalConsole( "Window State: Normal" ); - } + displayWindowElements( win.window ); } } } } +/* + * Display window atoms + */ +void WindowCtrlUnix::displayWindowElements( Window window ) +{ + QString name = atomName( m_display, window ); + emit signalConsole( QString( "Atom name: %1" ).arg( name ) ); + + QStringList types = atomWindowType( m_display, window ); + foreach( QString type, types ) + { + emit signalConsole( QString( "Atom type: %1" ).arg( type ) ); + } + + QStringList states = atomState( m_display, window ); + + bool max_vert = false; + bool max_horz = false; + bool hidden = false; + + foreach( QString state, states ) + { + emit signalConsole( QString( "Atom state: %1" ).arg( state ) ); + + int state_code = WindowStates.indexOf( state ) ; + + switch( state_code ) + { + case STATE_MAXIMIZED_VERT: + { + max_vert = true; + break; + } + + case STATE_MAXIMIZED_HORZ: + { + max_horz = true; + break; + } + + case STATE_HIDDEN: + { + hidden = true; + break; + } + } + } + + if( states.length() > 0 ) + { + if( hidden ) + { + emit signalConsole( "Window State: Hidden" ); + } + else + if( max_vert && max_horz ) + { + emit signalConsole( "Window State: Maximize" ); + } + else + { + emit signalConsole( "Window State: Normal" ); + } + } + else + { + emit signalConsole( "Window State: Normal" ); + } +} + + /* * Get the Thunderbird window ID */ +quint64 WindowCtrlUnix::getWinId() +{ + return m_tb_window; +} + + +/* + * Get the Thunderbird window IDs + */ QList< quint64 > WindowCtrlUnix::getWinIds() { return m_tb_windows; @@ -315,98 +383,6 @@ void WindowCtrlUnix::deleteWindow( quint64 window ) } -/* - * Find a window by PID - */ -void WindowCtrlUnix::findWindow( pid_t pid ) -{ - QList< WindowItem > windows = listXWindows( m_display, m_root_window ); - - // Get the PID property atom. - Atom atom_PID = XInternAtom( m_display, "_NET_WM_PID", True ); - if( atom_PID == None ) - { - emit signalConsole( QString( "No such atom _NET_WM_PID" ) ); - } - - foreach( WindowItem win, windows ) - { - Atom type; - int format; - unsigned long nItems; - unsigned long bytesAfter; - - unsigned char* propPID = nullptr; - if( Success == XGetWindowProperty( m_display, win.window, atom_PID, 0, 1, False, XA_CARDINAL, - &type, &format, &nItems, &bytesAfter, &propPID ) ) - { - if( propPID != nullptr ) - { - if( pid == *((reinterpret_cast( propPID ) ) ) ) - { - char* name = nullptr; - XFetchName( m_display, win.window, &name ); - - emit signalConsole( QString( "Found: Level %1, XID %2, Name %3" ).arg( win.level ).arg( win.window ).arg( name ) ); - - - QString atom_name = atomName( m_display, win.window ); - emit signalConsole( QString( "Atom Name %1" ).arg( atom_name ) ); - - QStringList states = atomState( m_display, win.window ); - foreach( QString state, states ) - { - emit signalConsole( QString( "Atom state: %1" ).arg( state ) ); - } - - QStringList types = atomWindowType( m_display, win.window ); - foreach( QString type, types ) - { - emit signalConsole( QString( "Atom type: %1" ).arg( type ) ); - } - - /* - * Cleanup - */ - if( name != nullptr ) - { - XFree( name ); - } - } - - XFree( propPID ); - } - } - } -} - - -#ifdef RAW_EVENT_SEND - -bool WindowCtrlUnix::generateEvent() -{ - XClientMessageEvent event; - Atom prop; - - prop = XInternAtom( m_display, "WM_CHANGE_STATE", False ); - if( prop == None ) - { - return false; - } - - event.type = ClientMessage; - event.window = m_tb_window; - event.message_type = prop; - event.format = 32; - event.data.l[0] = IconicState; - return XSendEvent( m_display, m_root_window, False, - SubstructureRedirectMask|SubstructureNotifyMask, - reinterpret_cast( &event ) ); -} - -#endif - - /* * Get the X11 window list */ diff --git a/app/SysTray-X/windowctrl-unix.h b/app/SysTray-X/windowctrl-unix.h index c2ebedd..cac8066 100644 --- a/app/SysTray-X/windowctrl-unix.h +++ b/app/SysTray-X/windowctrl-unix.h @@ -118,7 +118,7 @@ class WindowCtrlUnix : public QObject qint64 getPpid(); /** - * @brief findWindow. Find window with title. + * @brief findWindow. Find window by (sub)title. * * @param title The title to find. * @@ -126,6 +126,13 @@ class WindowCtrlUnix : public QObject */ bool findWindow( const QString& title ); + /** + * @brief findWindow. Find window of a process. + * + * @param pid The process id. + */ + void findWindow( qint64 pid ); + /** * @brief displayWindowElements. Display window elements (atoms). * @@ -133,12 +140,26 @@ class WindowCtrlUnix : public QObject */ void displayWindowElements( const QString& title ); + /** + * @brief displayWindowElements. Display window elements (atoms). + * + * @param window The window. + */ + void displayWindowElements( Window window ); + + /** + * @brief getWinId. Get the Thunderbird window ID. + * + * @return The window ID. + */ + quint64 getWinId(); + /** * @brief getWinIds. Get the Thunderbird window IDs. * - * @return The list of window IDs. + * @return The list of window ID. */ - QList< quint64 > getWinIds(); + QList< quint64 > getWinIds(); /** * @brief minimizeWindow. Minimize window. @@ -170,17 +191,6 @@ class WindowCtrlUnix : public QObject */ void deleteWindow( quint64 window ); - - - /** - * @brief findWindow. Find window of a process. - * - * @param pid The process id. - */ - void findWindow( int pid ); - - void setAtomState(); - private: /** @@ -268,9 +278,14 @@ class WindowCtrlUnix : public QObject Window m_root_window; /** - * @brief m_tb_window. The Thunderbird windows. + * @brief m_tb_window. The Thunderbird window. */ - QList< quint64 > m_tb_windows; + quint64 m_tb_window; + + /** + * @brief m_tb_windows. The Thunderbird windows (used by title search). + */ + QList< quint64 > m_tb_windows; }; #endif // WINDOWCTRLUNIX_H diff --git a/app/SysTray-X/windowctrl.cpp b/app/SysTray-X/windowctrl.cpp index 767b29f..3d58f80 100644 --- a/app/SysTray-X/windowctrl.cpp +++ b/app/SysTray-X/windowctrl.cpp @@ -42,6 +42,11 @@ WindowCtrl::WindowCtrl( Preferences* pref, QObject *parent ) : */ m_pid = QCoreApplication::applicationPid(); m_ppid = getPpid(); + + /* + * Get the TB window + */ + findWindow( m_ppid ); } @@ -51,11 +56,10 @@ void WindowCtrl::slotWindowTest1() // Do something. - findWindow( "- Mozilla Thunderbird" ); - displayWindowElements( "- Mozilla Thunderbird" ); +// findWindow( "- Mozilla Thunderbird" ); +// displayWindowElements( "- Mozilla Thunderbird" ); // findWindow( 4313 ); - -// captureWindow( "- Mozilla Thunderbird" ); + displayWindowElements( getWinId() ); emit signalConsole("Test 1 done"); } @@ -121,17 +125,11 @@ void WindowCtrl::slotWindowState( QString state ) if( state == "normal" ) { - foreach( quint64 win_id, getWinIds() ) - { - hideWindow( win_id, false ); - } + hideWindow( getWinId(), false ); } else { - foreach( quint64 win_id, getWinIds() ) - { - hideWindow( win_id, m_minimize_hide ); - } + hideWindow( getWinId(), m_minimize_hide ); } emit signalConsole( "New state: " + state ); @@ -148,24 +146,18 @@ void WindowCtrl::slotShowHide() { m_state = "normal"; - foreach( quint64 win_id, getWinIds() ) - { - normalizeWindow( win_id ); + normalizeWindow( getWinId() ); - emit signalConsole("Normalize"); - } + emit signalConsole("Normalize"); // emit signalWindowNormal(); // TB window control } else { m_state = "minimized"; - foreach( quint64 win_id, getWinIds() ) - { - minimizeWindow( win_id, m_minimize_hide ); + minimizeWindow( getWinId(), m_minimize_hide ); - emit signalConsole("Minimize"); - } + emit signalConsole("Minimize"); // emit signalWindowMinimize(); // TB window control @@ -178,8 +170,5 @@ void WindowCtrl::slotShowHide() */ void WindowCtrl::slotClose() { - foreach( quint64 win_id, getWinIds() ) - { - deleteWindow( win_id ); - } + deleteWindow( getWinId() ); }