Minimize / Normalize using X11

This commit is contained in:
Ximi1970
2020-02-16 22:24:17 +01:00
parent 3bb420b5c1
commit 5900687fa7
9 changed files with 304 additions and 99 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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