mirror of
https://github.com/Ximi1970/systray-x.git
synced 2025-10-26 07:46:09 +01:00
Switch to find window by pid
This commit is contained in:
@@ -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
|
||||
==========================================
|
||||
|
||||
@@ -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<qint64 *>( 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<pid_t *>( 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<XEvent *>( &event ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Get the X11 window list
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user