Add x11 state monitor

This commit is contained in:
Ximi1970
2021-01-10 22:38:10 +01:00
parent cce6297cce
commit 257378890c
3 changed files with 265 additions and 87 deletions

View File

@@ -20,8 +20,10 @@
/*
* Qt includes
*/
#include <QTimer>
#include <QFileInfo>
/*
* Constructor
*/
@@ -40,6 +42,137 @@ WindowCtrlUnix::WindowCtrlUnix( QObject *parent ) : QObject( parent )
* Get the base display and window
*/
m_display = OpenDisplay();
/*
* State monitor
*/
m_x11_window_states_monitor = new QTimer( this );
connect( m_x11_window_states_monitor, &QTimer::timeout, this, &WindowCtrlUnix::x11WindowStatesMonitor );
m_x11_window_states_monitor->start( STATES_MONITOR_TIMEOUT );
}
/*
* Thunderbird x11 window states monitor
*/
void WindowCtrlUnix::x11WindowStatesMonitor()
{
/*
* Stop the timer
*/
m_x11_window_states_monitor->stop();
/*
* Update the states
*/
updateX11WindowStates();
/*
* Start the timer
*/
m_x11_window_states_monitor->start( STATES_MONITOR_TIMEOUT );
}
/*
* Update the Thunderbird x11 window states
*/
void WindowCtrlUnix::updateX11WindowStates()
{
/*
* Get the x11 window states
*/
for( int i = 0 ; i < m_tb_windows.length() ; ++i )
{
/*
* Get the WM_STATE
*/
qint32 n_wm_state;
void* wm_state_ptr = GetWindowProperty( m_display, m_tb_windows.at( i ), "WM_STATE", &n_wm_state );
/*
* Get the state
*/
int state = -1;
if( wm_state_ptr != nullptr )
{
state = *reinterpret_cast<long *>( wm_state_ptr );
Free( wm_state_ptr );
}
/*
* Get the _NET_WM_STATE
*/
qint32 n_net_wm_state;
void* net_wm_state_ptr = GetWindowProperty( m_display, m_tb_windows.at( i ), "_NET_WM_STATE", &n_net_wm_state );
/*
* Get the atoms
*/
QStringList atom_list;
if( net_wm_state_ptr != nullptr )
{
for( qint32 j = 0 ; j < n_net_wm_state ; ++j )
{
char* atom_name = GetAtomName( m_display, reinterpret_cast<long *>( net_wm_state_ptr )[ j ] );
atom_list.append( atom_name );
if( atom_name )
{
Free( atom_name );
}
}
Free( net_wm_state_ptr );
}
/*
* Determine the state of the window
*/
Preferences::WindowState current_state;
if( state == -1 || state == 0 || ( atom_list.contains( "_NET_WM_STATE_HIDDEN" ) && atom_list.contains( "_NET_WM_STATE_SKIP_TASKBAR" ) ) )
{
/*
* Docked
*/
current_state = Preferences::STATE_DOCKED;
}
else if( state == 3 || atom_list.contains( "_NET_WM_STATE_HIDDEN" ) )
{
/*
* Minimized
*/
current_state = Preferences::STATE_MINIMIZED;
}
else
{
/*
* Normal
*/
current_state = Preferences::STATE_NORMAL;
}
m_tb_window_states_x11[ i ] = current_state;
if( ( current_state == Preferences::STATE_MINIMIZED || current_state == Preferences::STATE_DOCKED ) && current_state != getWindowState( m_tb_windows.at( i ) ) )
{
#ifdef DEBUG_DISPLAY_ACTIONS_DETAILS
emit signalConsole( QString( "WinID %1, state: %2").arg( m_tb_windows.at( i ) ).
arg( Preferences::WindowStateString.at( m_tb_window_states[ m_tb_windows.at( i ) ] ) ) );
for( int j = 0 ; j < atom_list.length() ; ++j )
{
emit signalConsole( QString( "Atom: %1").arg( atom_list.at( j ) ) );
}
emit signalConsole( QString( "State x11: %1").arg( state ) );
#endif
minimizeWindow( m_tb_windows.at( i ) );
}
}
}
@@ -177,99 +310,102 @@ void WindowCtrlUnix::findWindows( qint64 pid )
Free( types_ptr );
}
qint32 n_wm_state;
void* wm_state_ptr = GetWindowProperty( m_display, win.window, "WM_STATE", &n_wm_state );
qint32 n_net_wm_state;
void* net_wm_state_ptr = GetWindowProperty( m_display, win.window, "_NET_WM_STATE", &n_net_wm_state );
if( ( wm_state_ptr != nullptr || net_wm_state_ptr != nullptr ) && types.contains( "_NET_WM_WINDOW_TYPE_NORMAL" ) )
if( types.contains( "_NET_WM_WINDOW_TYPE_NORMAL" ) )
{
m_tb_windows.append( win.window );
qint32 n_wm_state;
void* wm_state_ptr = GetWindowProperty( m_display, win.window, "WM_STATE", &n_wm_state );
if( !m_tb_window_states.contains( win.window ) )
qint32 n_net_wm_state;
void* net_wm_state_ptr = GetWindowProperty( m_display, win.window, "_NET_WM_STATE", &n_net_wm_state );
if( ( wm_state_ptr != nullptr || net_wm_state_ptr != nullptr ) )
{
/*
* Set the startup state
*/
m_tb_window_states[ win.window ] = Preferences::STATE_NORMAL;
}
m_tb_windows.append( win.window );
QPoint point;
if( m_tb_windows.length() <= old_positions.length() )
{
point = old_positions.at( m_tb_windows.length() - 1 );
}
m_tb_window_positions.append( point );
/*
* Get the current state
*/
QStringList atom_list;
if( net_wm_state_ptr != nullptr )
{
for( qint32 j = 0 ; j < n_net_wm_state ; ++j )
if( !m_tb_window_states.contains( win.window ) )
{
char* atom_name = GetAtomName( m_display, reinterpret_cast<long *>( net_wm_state_ptr )[ j ] );
atom_list.append( atom_name );
if( atom_name )
{
Free( atom_name );
}
/*
* Set the startup state
*/
m_tb_window_states[ win.window ] = Preferences::STATE_NORMAL;
}
}
int state = -1;
if( wm_state_ptr != nullptr )
{
state = *reinterpret_cast<long *>( wm_state_ptr );
}
QPoint point;
if( m_tb_windows.length() <= old_positions.length() )
{
point = old_positions.at( m_tb_windows.length() - 1 );
}
m_tb_window_positions.append( point );
/*
* Get the current state
*/
QStringList atom_list;
if( net_wm_state_ptr != nullptr )
{
for( qint32 j = 0 ; j < n_net_wm_state ; ++j )
{
char* atom_name = GetAtomName( m_display, reinterpret_cast<long *>( net_wm_state_ptr )[ j ] );
atom_list.append( atom_name );
if( atom_name )
{
Free( atom_name );
}
}
}
int state = -1;
if( wm_state_ptr != nullptr )
{
state = *reinterpret_cast<long *>( wm_state_ptr );
}
#ifdef DEBUG_DISPLAY_ACTIONS_DETAILS
emit signalConsole( QString( "WinID %1, state: %2").arg(win.window ).
arg( Preferences::WindowStateString.at( m_tb_window_states[ win.window ] ) ) );
emit signalConsole( QString( "WinID %1, state: %2").arg(win.window ).
arg( Preferences::WindowStateString.at( m_tb_window_states[ win.window ] ) ) );
for( int j = 0 ; j < atom_list.length() ; ++j )
{
emit signalConsole( QString( "Atom: %1").arg( atom_list.at( j ) ) );
}
for( int j = 0 ; j < atom_list.length() ; ++j )
{
emit signalConsole( QString( "Atom: %1").arg( atom_list.at( j ) ) );
}
emit signalConsole( QString( "State x11: %1").arg( state ) );
emit signalConsole( QString( "State x11: %1").arg( state ) );
#endif
if( state == -1 || state == 0 || ( atom_list.contains( "_NET_WM_STATE_HIDDEN" ) && atom_list.contains( "_NET_WM_STATE_SKIP_TASKBAR" ) ) )
{
/*
* Docked
*/
m_tb_window_states_x11.append( Preferences::STATE_DOCKED );
}
else if( state == 3 || atom_list.contains( "_NET_WM_STATE_HIDDEN" ) )
{
/*
* Minimized
*/
m_tb_window_states_x11.append( Preferences::STATE_MINIMIZED );
}
else
{
/*
* Normal
*/
m_tb_window_states_x11.append( Preferences::STATE_NORMAL );
}
if( state == -1 || state == 0 || ( atom_list.contains( "_NET_WM_STATE_HIDDEN" ) && atom_list.contains( "_NET_WM_STATE_SKIP_TASKBAR" ) ) )
{
/*
* Docked
*/
m_tb_window_states_x11.append( Preferences::STATE_DOCKED );
}
else if( state == 3 || atom_list.contains( "_NET_WM_STATE_HIDDEN" ) )
{
/*
* Minimized
*/
m_tb_window_states_x11.append( Preferences::STATE_MINIMIZED );
}
else
{
/*
* Normal
*/
m_tb_window_states_x11.append( Preferences::STATE_NORMAL );
}
if( wm_state_ptr != nullptr )
{
Free( wm_state_ptr );
}
if( wm_state_ptr != nullptr )
{
Free( wm_state_ptr );
}
if( net_wm_state_ptr != nullptr )
{
Free( net_wm_state_ptr );
if( net_wm_state_ptr != nullptr )
{
Free( net_wm_state_ptr );
}
}
}
}
@@ -680,7 +816,7 @@ void WindowCtrlUnix::normalizeWindow( quint64 window )
/*
* Set focus
*/
SetInputFocus( m_display, window );
// SetInputFocus( m_display, window );
/*
* Flush the pipes

View File

@@ -18,12 +18,19 @@
* Qt includes
*/
#include <QObject>
#include <QMutex>
#include <QMap>
#include <QPoint>
/*
* Predefines
*/
class QTimer;
/*
* Monitor timeout (ms)
*/
#define STATES_MONITOR_TIMEOUT 500
/**
* @brief The WindowCtrlUnix class.
@@ -244,8 +251,18 @@ class WindowCtrlUnix : public QObject
*/
void setPositions( QList< QPoint > window_positions );
/**
* @brief updateX11WindowStates. Update the x11 window states.
*/
void updateX11WindowStates();
private:
/**
* @brief x11WindowStatesMonitor. Monitor the Thunderbird x11 window states.
*/
void x11WindowStatesMonitor();
/**
* @brief listXWindows. Get all the windows.
*
@@ -275,6 +292,11 @@ class WindowCtrlUnix : public QObject
private:
/**
* @brief m_x11_window_states_monitor. Timer to monitor the Thunderbird window states.
*/
QTimer* m_x11_window_states_monitor;
/**
* @brief m_display. Pointer to the main display.
*/

View File

@@ -180,18 +180,18 @@ void WindowCtrl::slotWindowState( Preferences::WindowState state )
#ifdef Q_OS_UNIX
/*
* Update the TB windows and states
*/
findWindows( m_ppid );
QList< quint64 > win_ids = getWinIds();
/*
* Minimize all?
*/
if( state == Preferences::STATE_MINIMIZED_ALL || state == Preferences::STATE_MINIMIZED_ALL_STARTUP )
{
/*
* Update the TB windows and states
*/
findWindows( m_ppid );
QList< quint64 > win_ids = getWinIds();
if( state == Preferences::STATE_MINIMIZED || state == Preferences::STATE_MINIMIZED_ALL )
{
updatePositions();
@@ -217,8 +217,20 @@ void WindowCtrl::slotWindowState( Preferences::WindowState state )
}
else
{
/*
* Let the montor handle this
*/
#ifdef MONITOR
if( state == Preferences::STATE_MINIMIZED )
{
{
/*
* Update the TB windows and states
*/
findWindows( m_ppid );
QList< quint64 > win_ids = getWinIds();
/*
* Compare the x11 states and the internal states
*/
@@ -232,6 +244,8 @@ void WindowCtrl::slotWindowState( Preferences::WindowState state )
}
}
}
#endif
}
#else
@@ -311,6 +325,12 @@ void WindowCtrl::slotShowHide()
}
}
/*
* Update the TB windows
*/
findWindows( m_ppid );
// updateX11WindowStates(); // WM_STATE not synced????
#ifdef DEBUG_DISPLAY_ACTIONS
emit signalConsole( "Show/Hide end" );
#endif