mirror of
https://github.com/Ximi1970/systray-x.git
synced 2025-10-26 07:46:09 +01:00
Minimize / Normalize using X11
This commit is contained in:
@@ -33,6 +33,13 @@ https://stackoverflow.com/questions/41622735/hide-window-from-linux-taskbar
|
||||
|
||||
|
||||
|
||||
minimize fullscreen Xlib OpenGL Window
|
||||
|
||||
https://stackoverflow.com/questions/6381098/minimize-fullscreen-xlib-opengl-window
|
||||
|
||||
|
||||
|
||||
|
||||
Intercept close event X11
|
||||
|
||||
https://stackoverflow.com/questions/1157364/intercept-wm-delete-window-on-x11
|
||||
|
||||
@@ -32,6 +32,7 @@ DebugWidget::DebugWidget( Preferences* pref, QWidget* parent ) : QWidget( parent
|
||||
*/
|
||||
connect( m_ui->test1PushButton, &QPushButton::clicked, this, &DebugWidget::slotHandleTest1Button);
|
||||
connect( m_ui->test2PushButton, &QPushButton::clicked, this, &DebugWidget::slotHandleTest2Button);
|
||||
connect( m_ui->test3PushButton, &QPushButton::clicked, this, &DebugWidget::slotHandleTest3Button);
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +159,15 @@ void DebugWidget::slotHandleTest2Button()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle test button 3 click
|
||||
*/
|
||||
void DebugWidget::slotHandleTest3Button()
|
||||
{
|
||||
emit signalTest3ButtonClicked();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle console signal
|
||||
*/
|
||||
|
||||
@@ -92,6 +92,11 @@ class DebugWidget : public QWidget
|
||||
*/
|
||||
void signalTest2ButtonClicked();
|
||||
|
||||
/**
|
||||
* @brief signalTestButton3Clicked. Signal the test button was clicked.
|
||||
*/
|
||||
void signalTest3ButtonClicked();
|
||||
|
||||
public slots:
|
||||
|
||||
/**
|
||||
@@ -144,6 +149,11 @@ class DebugWidget : public QWidget
|
||||
*/
|
||||
void slotHandleTest2Button();
|
||||
|
||||
/**
|
||||
* @brief slotHandleTest2Button. Handle a click on the test button.
|
||||
*/
|
||||
void slotHandleTest3Button();
|
||||
|
||||
/**
|
||||
* @brief slotConsole. Handle console signal.
|
||||
*
|
||||
|
||||
@@ -19,51 +19,10 @@
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>381</width>
|
||||
<height>281</height>
|
||||
<height>288</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="rawDataLengthLabel">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QPushButton" name="test1PushButton">
|
||||
<property name="text">
|
||||
<string>Test 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="3">
|
||||
<widget class="QLabel" name="errorLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QLabel" name="messageLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
@@ -77,6 +36,29 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QPushButton" name="test2PushButton">
|
||||
<property name="text">
|
||||
<string>Test 2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="4">
|
||||
<widget class="QTextEdit" name="textEdit"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="unreadMailTextLabel">
|
||||
<property name="text">
|
||||
@@ -84,13 +66,38 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3">
|
||||
<widget class="QTextEdit" name="textEdit"/>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QPushButton" name="test2PushButton">
|
||||
<item row="4" column="0" colspan="4">
|
||||
<widget class="QLabel" name="errorLabel">
|
||||
<property name="text">
|
||||
<string>Test 2</string>
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="4">
|
||||
<widget class="QLabel" name="messageLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QPushButton" name="test1PushButton">
|
||||
<property name="text">
|
||||
<string>Test 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="rawDataLengthLabel">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1" colspan="3">
|
||||
<widget class="QLabel" name="rawDataLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -101,10 +108,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1" colspan="2">
|
||||
<widget class="QLabel" name="rawDataLabel">
|
||||
<item row="7" column="2">
|
||||
<widget class="QPushButton" name="test3PushButton">
|
||||
<property name="text">
|
||||
<string/>
|
||||
<string>Test 3</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -80,6 +80,7 @@ SysTrayX::SysTrayX( QObject *parent ) : QObject( parent )
|
||||
connect( m_win_ctrl, &WindowCtrl::signalConsole, m_debug, &DebugWidget::slotConsole );
|
||||
connect( m_debug, &DebugWidget::signalTest1ButtonClicked, m_win_ctrl, &WindowCtrl::slotWindowTest1 );
|
||||
connect( m_debug, &DebugWidget::signalTest2ButtonClicked, m_win_ctrl, &WindowCtrl::slotWindowTest2 );
|
||||
connect( m_debug, &DebugWidget::signalTest3ButtonClicked, m_win_ctrl, &WindowCtrl::slotWindowTest3 );
|
||||
|
||||
/*
|
||||
* Connect preferences signals
|
||||
|
||||
@@ -6,39 +6,29 @@
|
||||
* System includes
|
||||
*/
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
WindowCtrlUnix::WindowCtrlUnix( QObject *parent ) : QObject( parent )
|
||||
{
|
||||
|
||||
/*
|
||||
* Get the base display and window
|
||||
*/
|
||||
m_display = XOpenDisplay( ":0" );
|
||||
m_screen = 0;
|
||||
m_root_window = XDefaultRootWindow( m_display );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the X11 window list
|
||||
* Get the Thunderbird window ID
|
||||
*/
|
||||
QList< WindowCtrlUnix::WindowItem > WindowCtrlUnix::listXWindows( Display *display, Window window, int level )
|
||||
unsigned long WindowCtrlUnix::getWId()
|
||||
{
|
||||
Window root;
|
||||
Window parent;
|
||||
Window *children;
|
||||
unsigned int childrenCount;
|
||||
|
||||
QList< WindowItem > windows;
|
||||
if( XQueryTree( display, window, &root, &parent, &children, &childrenCount) )
|
||||
{
|
||||
for( unsigned int i = 0; i < childrenCount; ++i )
|
||||
{
|
||||
windows.append( WindowItem( children[ i ], level ) );
|
||||
windows.append( listXWindows( display, children[ i ], level + 1) );
|
||||
}
|
||||
|
||||
XFree( children );
|
||||
}
|
||||
|
||||
return windows;
|
||||
return m_tb_window;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,14 +37,12 @@ QList< WindowCtrlUnix::WindowItem > WindowCtrlUnix::listXWindows( Display *dis
|
||||
*/
|
||||
bool WindowCtrlUnix::findWindow( const QString& title, unsigned long& window )
|
||||
{
|
||||
Display *display = XOpenDisplay( ":0.0" );
|
||||
Window rootWindow = XDefaultRootWindow( display );
|
||||
QList< WindowItem > windows = listXWindows( display, rootWindow );
|
||||
QList< WindowItem > windows = listXWindows( m_display, m_root_window );
|
||||
|
||||
foreach( WindowItem win, windows )
|
||||
{
|
||||
char *name = nullptr;
|
||||
if( XFetchName( display, win.window, &name ) > 0 ) {
|
||||
if( XFetchName( m_display, win.window, &name ) > 0 ) {
|
||||
QString win_name( name );
|
||||
|
||||
XFree( name );
|
||||
@@ -63,17 +51,17 @@ bool WindowCtrlUnix::findWindow( const QString& title, unsigned long& window
|
||||
emit signalConsole( QString( "Found: Level %1, XID %2, Name %3" ).arg( win.level ).arg( win.window ).arg( win_name ) );
|
||||
|
||||
|
||||
QString name = atomName( display, win.window );
|
||||
QString name = atomName( m_display, win.window );
|
||||
emit signalConsole( QString( "Atom name: %1" ).arg( name ) );
|
||||
|
||||
|
||||
QStringList types = atomWindowType( display, win.window );
|
||||
QStringList types = atomWindowType( m_display, win.window );
|
||||
foreach( QString type, types )
|
||||
{
|
||||
emit signalConsole( QString( "Atom type: %1" ).arg( type ) );
|
||||
}
|
||||
|
||||
QStringList states = atomState( display, win.window );
|
||||
QStringList states = atomState( m_display, win.window );
|
||||
|
||||
bool max_vert = false;
|
||||
bool max_horz = false;
|
||||
@@ -129,8 +117,9 @@ bool WindowCtrlUnix::findWindow( const QString& title, unsigned long& window
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the XID
|
||||
* Store and return the XID
|
||||
*/
|
||||
m_tb_window = win.window;
|
||||
window = win.window;
|
||||
|
||||
return true;
|
||||
@@ -147,12 +136,10 @@ bool WindowCtrlUnix::findWindow( const QString& title, unsigned long& window
|
||||
*/
|
||||
void WindowCtrlUnix::findWindow( pid_t pid )
|
||||
{
|
||||
Display *display = XOpenDisplay( ":0.0" );
|
||||
Window rootWindow = XDefaultRootWindow( display );
|
||||
QList< WindowItem > windows = listXWindows( display, rootWindow );
|
||||
QList< WindowItem > windows = listXWindows( m_display, m_root_window );
|
||||
|
||||
// Get the PID property atom.
|
||||
Atom atom_PID = XInternAtom( display, "_NET_WM_PID", True );
|
||||
Atom atom_PID = XInternAtom( m_display, "_NET_WM_PID", True );
|
||||
if( atom_PID == None )
|
||||
{
|
||||
emit signalConsole( QString( "No such atom _NET_WM_PID" ) );
|
||||
@@ -166,7 +153,7 @@ void WindowCtrlUnix::findWindow( pid_t pid )
|
||||
unsigned long bytesAfter;
|
||||
|
||||
unsigned char* propPID = nullptr;
|
||||
if( Success == XGetWindowProperty( display, win.window, atom_PID, 0, 1, False, XA_CARDINAL,
|
||||
if( Success == XGetWindowProperty( m_display, win.window, atom_PID, 0, 1, False, XA_CARDINAL,
|
||||
&type, &format, &nItems, &bytesAfter, &propPID ) )
|
||||
{
|
||||
if( propPID != nullptr )
|
||||
@@ -174,21 +161,21 @@ void WindowCtrlUnix::findWindow( pid_t pid )
|
||||
if( pid == *((reinterpret_cast<pid_t *>( propPID ) ) ) )
|
||||
{
|
||||
char* name = nullptr;
|
||||
XFetchName( display, win.window, &name );
|
||||
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( display, win.window );
|
||||
QString atom_name = atomName( m_display, win.window );
|
||||
emit signalConsole( QString( "Atom Name %1" ).arg( atom_name ) );
|
||||
|
||||
QStringList states = atomState( display, win.window );
|
||||
QStringList states = atomState( m_display, win.window );
|
||||
foreach( QString state, states )
|
||||
{
|
||||
emit signalConsole( QString( "Atom state: %1" ).arg( state ) );
|
||||
}
|
||||
|
||||
QStringList types = atomWindowType( display, win.window );
|
||||
QStringList types = atomWindowType( m_display, win.window );
|
||||
foreach( QString type, types )
|
||||
{
|
||||
emit signalConsole( QString( "Atom type: %1" ).arg( type ) );
|
||||
@@ -210,6 +197,117 @@ void WindowCtrlUnix::findWindow( pid_t pid )
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Minimize a window
|
||||
*/
|
||||
void WindowCtrlUnix::minimizeWindow( Window window )
|
||||
{
|
||||
XIconifyWindow( m_display, window, m_screen );
|
||||
XFlush( m_display );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Normalize a window
|
||||
*/
|
||||
void WindowCtrlUnix::normalizeWindow( Window window )
|
||||
{
|
||||
// XMapRaised( m_display, m_tb_window );
|
||||
XMapWindow( m_display, window );
|
||||
XFlush( m_display );
|
||||
}
|
||||
|
||||
|
||||
#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
|
||||
|
||||
#ifdef CHANGE_PROP
|
||||
|
||||
void WindowCtrlUnix::setAtomState()
|
||||
{
|
||||
char prop_name[] = "_NET_WM_STATE";
|
||||
Atom prop = XInternAtom( m_display, prop_name, True );
|
||||
Atom prop_hidden = XInternAtom( m_display, WindowStates[ STATE_HIDDEN ].toUtf8(), True );
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long remain;
|
||||
unsigned long len;
|
||||
unsigned char* list = nullptr;
|
||||
|
||||
QStringList states;
|
||||
|
||||
if( XGetWindowProperty( m_display, m_tb_window, prop, 0, sizeof( Atom ), False, XA_ATOM,
|
||||
&type, &format, &len, &remain, &list ) == Success )
|
||||
{
|
||||
emit signalConsole( QString( "Atom state" ) );
|
||||
|
||||
if( XChangeProperty( m_display, m_tb_window, prop, XA_ATOM, format, PropModeAppend, reinterpret_cast<unsigned char*>( &prop_hidden ), 1 ) == Success )
|
||||
{
|
||||
emit signalConsole( QString( "Atom state appended: %1" ).arg( WindowStates[ STATE_HIDDEN ] ) );
|
||||
}
|
||||
|
||||
emit signalConsole( QString( "Atom state done" ) );
|
||||
}
|
||||
|
||||
if( list )
|
||||
{
|
||||
XFree( list );
|
||||
}
|
||||
|
||||
XFlush( m_display );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Get the X11 window list
|
||||
*/
|
||||
QList< WindowCtrlUnix::WindowItem > WindowCtrlUnix::listXWindows( Display *display, Window window, int level )
|
||||
{
|
||||
Window root;
|
||||
Window parent;
|
||||
Window *children;
|
||||
unsigned int childrenCount;
|
||||
|
||||
QList< WindowItem > windows;
|
||||
if( XQueryTree( display, window, &root, &parent, &children, &childrenCount) )
|
||||
{
|
||||
for( unsigned int i = 0; i < childrenCount; ++i )
|
||||
{
|
||||
windows.append( WindowItem( children[ i ], level ) );
|
||||
windows.append( listXWindows( display, children[ i ], level + 1) );
|
||||
}
|
||||
|
||||
XFree( children );
|
||||
}
|
||||
|
||||
return windows;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the title of the window
|
||||
*/
|
||||
|
||||
@@ -110,6 +110,13 @@ class WindowCtrlUnix : public QObject
|
||||
*/
|
||||
explicit WindowCtrlUnix( QObject *parent = nullptr );
|
||||
|
||||
/**
|
||||
* @brief getWId. Get the Thunderbird windows ID.
|
||||
*
|
||||
* @return The ID.
|
||||
*/
|
||||
unsigned long getWId();
|
||||
|
||||
/**
|
||||
* @brief findWindow. Find window with title.
|
||||
*
|
||||
@@ -127,6 +134,23 @@ class WindowCtrlUnix : public QObject
|
||||
*/
|
||||
void findWindow( int pid );
|
||||
|
||||
|
||||
void setAtomState();
|
||||
|
||||
/**
|
||||
* @brief minimizeWindow. Minimize window.
|
||||
*
|
||||
* @param window The window.
|
||||
*/
|
||||
void minimizeWindow( Window window );
|
||||
|
||||
/**
|
||||
* @brief normalizeWindow. Normalize window.
|
||||
*
|
||||
* @param window The window.
|
||||
*/
|
||||
void normalizeWindow( Window window );
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
@@ -195,6 +219,28 @@ class WindowCtrlUnix : public QObject
|
||||
* @param message The message.
|
||||
*/
|
||||
void signalConsole( QString message );
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief m_display. Pointer to the main display.
|
||||
*/
|
||||
Display* m_display;
|
||||
|
||||
/**
|
||||
* @brief m_screen. The screen number.
|
||||
*/
|
||||
int m_screen;
|
||||
|
||||
/**
|
||||
* @brief m_root_window. The root window.
|
||||
*/
|
||||
Window m_root_window;
|
||||
|
||||
/**
|
||||
* @brief m_tb_window. The Thunderbird window.
|
||||
*/
|
||||
Window m_tb_window;
|
||||
};
|
||||
|
||||
#endif // WINDOWCTRLUNIX_H
|
||||
|
||||
@@ -33,14 +33,14 @@ void WindowCtrl::slotWindowTest1()
|
||||
|
||||
// Do something.
|
||||
|
||||
// unsigned long win_id;
|
||||
// findWindow( "Debugging with Firefox Developer Tools - Mozilla Thunderbird", win_id );
|
||||
unsigned long win_id;
|
||||
findWindow( "Debugging with Firefox Developer Tools - Mozilla Thunderbird", win_id );
|
||||
// findWindow( "Mozilla Thunderbird", win_id );
|
||||
|
||||
// findWindow( 4313 );
|
||||
|
||||
|
||||
captureWindow( "Debugging with Firefox Developer Tools - Mozilla Thunderbird" );
|
||||
// captureWindow( "Debugging with Firefox Developer Tools - Mozilla Thunderbird" );
|
||||
|
||||
|
||||
emit signalConsole("Test 1 done");
|
||||
@@ -53,10 +53,36 @@ void WindowCtrl::slotWindowTest2()
|
||||
|
||||
// Do something.
|
||||
|
||||
unsigned long win_id = getWId();
|
||||
minimizeWindow( win_id );
|
||||
// normalizeWindow( win_id );
|
||||
|
||||
/*
|
||||
* Disconnect container?
|
||||
*/
|
||||
/*
|
||||
m_tb_window->setParent( nullptr );
|
||||
|
||||
delete m_tb_container;
|
||||
m_tb_container = nullptr;
|
||||
*/
|
||||
emit signalConsole("Test 2 done");
|
||||
}
|
||||
|
||||
|
||||
void WindowCtrl::slotWindowTest3()
|
||||
{
|
||||
emit signalConsole("Test 3 started");
|
||||
|
||||
// Do something.
|
||||
|
||||
unsigned long win_id = getWId();
|
||||
normalizeWindow( win_id );
|
||||
|
||||
emit signalConsole("Test 3 done");
|
||||
}
|
||||
|
||||
|
||||
// "Debugging with Firefox Developer Tools - Mozilla Thunderbird"
|
||||
|
||||
bool WindowCtrl::captureWindow( const QString& title )
|
||||
@@ -71,9 +97,9 @@ bool WindowCtrl::captureWindow( const QString& title )
|
||||
* Wrap Thunderbird window
|
||||
*/
|
||||
m_tb_window = QWindow::fromWinId( WinId );
|
||||
m_tb_container = QWidget::createWindowContainer( m_tb_window );
|
||||
m_tb_window->parent();
|
||||
|
||||
// container->hide();
|
||||
m_tb_container = QWidget::createWindowContainer( m_tb_window );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -103,11 +129,6 @@ void WindowCtrl::slotShowHide()
|
||||
if( m_tb_container )
|
||||
{
|
||||
m_tb_container->show();
|
||||
|
||||
// m_tb_window->setParent( nullptr );
|
||||
|
||||
// delete m_tb_container;
|
||||
// m_tb_container = nullptr;
|
||||
}
|
||||
} else {
|
||||
m_state = "minimized";
|
||||
|
||||
@@ -60,6 +60,11 @@ class WindowCtrl : public QObject
|
||||
*/
|
||||
void slotWindowTest2();
|
||||
|
||||
/**
|
||||
* @brief slotWindowTest3. Start a test.
|
||||
*/
|
||||
void slotWindowTest3();
|
||||
|
||||
/**
|
||||
* @brief slotWindowState. Handle the window state change signal.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user