Switch to find window by pid

This commit is contained in:
Ximi1970
2020-02-27 23:02:12 +01:00
parent 6fa06ca74e
commit 30ceb716cf
4 changed files with 188 additions and 200 deletions

View File

@@ -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
==========================================

View File

@@ -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
*/

View File

@@ -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

View File

@@ -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() );
}