Port oxygen decoration from X11 to XCB

- use xcb for shadow atom
- use xcb to handle sizegrip map/raised
- removed dependency upon QX11Info and QtX11Extras.
- moved window detection to xcb
icc-effect-5.14.5
Hugo Pereira Da Costa 2013-10-18 21:18:59 +02:00
parent b0ba49cbdf
commit b35a760b66
7 changed files with 73 additions and 68 deletions

View File

@ -28,8 +28,7 @@ target_link_libraries(kwin3_oxygen KF5::KConfigWidgets KF5::KGuiAddons KF5::KI18
target_link_libraries(kwin3_oxygen kdecorations oxygenstyle) target_link_libraries(kwin3_oxygen kdecorations oxygenstyle)
if(X11_FOUND) if(X11_FOUND)
target_link_libraries(kwin3_oxygen ${X11_X11_LIB} ${XCB_XCB_LIBRARIES}) target_link_libraries(kwin3_oxygen ${XCB_XCB_LIBRARIES})
target_link_libraries(kwin3_oxygen Qt5::X11Extras)
endif() endif()
install(TARGETS kwin3_oxygen DESTINATION ${PLUGIN_INSTALL_DIR}) install(TARGETS kwin3_oxygen DESTINATION ${PLUGIN_INSTALL_DIR})

View File

@ -31,7 +31,7 @@ target_link_libraries(kwin_oxygen_config KF5::KConfigCore KF5::KConfigGui KF5::K
target_link_libraries(kwin_oxygen_config kdecorations oxygenstyle oxygenstyleconfig) target_link_libraries(kwin_oxygen_config kdecorations oxygenstyle oxygenstyleconfig)
if(X11_FOUND) if(X11_FOUND)
target_link_libraries(kwin_oxygen_config ${X11_LIBRARIES}) target_link_libraries(kwin_oxygen_config ${XCB_LIBRARIES})
target_link_libraries(kwin_oxygen_config Qt5::X11Extras) target_link_libraries(kwin_oxygen_config Qt5::X11Extras)
endif() endif()

View File

@ -38,10 +38,7 @@
#include <QPushButton> #include <QPushButton>
#include <QX11Info> #include <QX11Info>
#include <X11/Xlib.h> #include <xcb/xcb.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <fixx11h.h>
namespace Oxygen namespace Oxygen
{ {
@ -49,7 +46,8 @@ namespace Oxygen
//_________________________________________________________ //_________________________________________________________
DetectDialog::DetectDialog( QWidget* parent ): DetectDialog::DetectDialog( QWidget* parent ):
QDialog( parent ), QDialog( parent ),
_grabber( 0 ) _grabber( 0 ),
_wmStateAtom( 0 )
{ {
// setup // setup
@ -58,6 +56,13 @@ namespace Oxygen
connect( buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL(clicked()), this, SLOT(close()) ); connect( buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL(clicked()), this, SLOT(close()) );
windowClassCheckBox->setChecked( true ); windowClassCheckBox->setChecked( true );
// create atom
xcb_connection_t* connection( QX11Info::connection() );
const QString atomName( QLatin1String( "WM_STATE" ) );
xcb_intern_atom_cookie_t cookie( xcb_intern_atom( connection, false, atomName.size(), qPrintable( atomName ) ) );
xcb_intern_atom_reply_t* reply( xcb_intern_atom_reply( connection, cookie, 0) );
if( reply ) _wmStateAtom = reply->atom;
} }
//_________________________________________________________ //_________________________________________________________
@ -135,30 +140,31 @@ namespace Oxygen
WId DetectDialog::findWindow() WId DetectDialog::findWindow()
{ {
Window root; // check atom
Window child; if( !_wmStateAtom ) return 0;
uint mask;
int rootX, rootY, x, y; xcb_connection_t* connection( QX11Info::connection() );
Window parent = reinterpret_cast<Window>( QX11Info::appRootWindow() ); xcb_window_t parent( QX11Info::appRootWindow() );
Atom wm_state = XInternAtom( QX11Info::display(), "WM_STATE", False );
// why is there a loop of only 10 here // why is there a loop of only 10 here
for( int i = 0; i < 10; ++i ) for( int i = 0; i < 10; ++i )
{ {
XQueryPointer( QX11Info::display(), parent, &root, &child, &rootX, &rootY, &x, &y, &mask );
if( child == None ) return 0; // query pointer
Atom type; xcb_query_pointer_reply_t* pointerReply( 0x0 );
int format;
unsigned long nitems, after;
unsigned char* prop;
if( XGetWindowProperty(
QX11Info::display(), child, wm_state, 0, 0, False,
AnyPropertyType, &type, &format, &nitems, &after, &prop ) == Success )
{ {
if( prop != NULL ) XFree( prop ); xcb_query_pointer_cookie_t cookie( xcb_query_pointer( connection, parent ) );
if( type != None ) return child; pointerReply = xcb_query_pointer_reply( connection, cookie, 0 );
} }
parent = child;
if( !( pointerReply && pointerReply->child ) ) return 0;
const xcb_window_t child( pointerReply->child );
xcb_get_property_cookie_t cookie( xcb_get_property( connection, 0, child, _wmStateAtom, XCB_GET_PROPERTY_TYPE_ANY, 0, 0) );
xcb_get_property_reply_t* reply( xcb_get_property_reply( connection, cookie, 0 ) );
if( reply && reply->type ) return child;
else parent = child;
} }
return 0; return 0;

View File

@ -40,6 +40,7 @@
#include <QLabel> #include <QLabel>
#include <kwindowsystem.h> #include <kwindowsystem.h>
#include <xcb/xcb.h>
namespace Oxygen namespace Oxygen
{ {
@ -100,6 +101,9 @@ namespace Oxygen
//! current window information //! current window information
KWindowInfo _info; KWindowInfo _info;
//! wm state atom
xcb_atom_t _wmStateAtom;
}; };
} // namespace } // namespace

View File

@ -43,13 +43,9 @@
#include <QLabel> #include <QLabel>
#include <QPainter> #include <QPainter>
#include <QBitmap> #include <QBitmap>
#include <QX11Info>
#include <QObjectList> #include <QObjectList>
#include <QMimeData> #include <QMimeData>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
namespace Oxygen namespace Oxygen
{ {
@ -2042,9 +2038,9 @@ namespace Oxygen
// create atom // create atom
if( !_shadowAtom ) if( !_shadowAtom )
{ _shadowAtom = XInternAtom( QX11Info::display(), "_KDE_NET_WM_SHADOW", False); } { _shadowAtom = helper().createAtom( QLatin1String( "_KDE_NET_WM_SHADOW" ) ); }
XDeleteProperty(QX11Info::display(), windowId(), _shadowAtom); xcb_delete_property( helper().xcbConnection(), (xcb_window_t) windowId(), _shadowAtom);
} }
} }

View File

@ -41,7 +41,7 @@
#include <QTextStream> #include <QTextStream>
#include <QTimerEvent> #include <QTimerEvent>
#include <X11/Xdefs.h> #include <xcb/xcb.h>
namespace Oxygen namespace Oxygen
{ {
@ -485,7 +485,7 @@ namespace Oxygen
QBasicTimer _dragStartTimer; QBasicTimer _dragStartTimer;
//! shadow atom //! shadow atom
Atom _shadowAtom; xcb_atom_t _shadowAtom;
}; };

View File

@ -34,8 +34,7 @@
#include <QPolygon> #include <QPolygon>
#include <QTimer> #include <QTimer>
#include <QX11Info> #include <xcb/xcb.h>
#include <X11/Xlib.h>
namespace Oxygen namespace Oxygen
{ {
@ -82,36 +81,37 @@ namespace Oxygen
//_____________________________________________ //_____________________________________________
void SizeGrip::activeChange( void ) void SizeGrip::activeChange( void )
{ XMapRaised( QX11Info::display(), winId() ); } {
static const uint32_t value = XCB_STACK_MODE_ABOVE;
xcb_configure_window( _client->helper().xcbConnection(), winId(), XCB_CONFIG_WINDOW_STACK_MODE, &value );
xcb_map_window( _client->helper().xcbConnection(), winId() );
}
//_____________________________________________ //_____________________________________________
void SizeGrip::embed( void ) void SizeGrip::embed( void )
{ {
xcb_window_t window_id = client().windowId(); xcb_window_t window_id = _client->windowId();
if( client().isPreview() ) { if( _client->isPreview() ) {
setParent( client().widget() ); setParent( _client->widget() );
} else if( window_id ) { } else if( window_id ) {
xcb_window_t current = window_id; xcb_window_t current = window_id;
auto *c = QX11Info::connection(); xcb_connection_t* connection = _client->helper().xcbConnection();
while( true ) while( true )
{ {
auto cookie = xcb_query_tree_unchecked(c, current); xcb_query_tree_cookie_t cookie = xcb_query_tree_unchecked( connection, current );
QScopedPointer<xcb_query_tree_reply_t, QScopedPointerPodDeleter> tree(xcb_query_tree_reply(c, cookie, nullptr)); QScopedPointer<xcb_query_tree_reply_t, QScopedPointerPodDeleter> tree(xcb_query_tree_reply( connection, cookie, nullptr ) );
if (tree.isNull()) { if (tree.isNull()) break;
break;
} if (tree->parent && tree->parent != tree->root && tree->parent != current) current = tree->parent;
if (tree->parent && tree->parent != tree->root && tree->parent != current) { else break;
current = tree->parent;
} else {
break;
}
} }
// reparent // reparent
xcb_reparent_window(c, winId(), current, 0, 0); xcb_reparent_window( connection, winId(), current, 0, 0 );
} else { } else {
hide(); hide();
@ -133,9 +133,9 @@ namespace Oxygen
{ {
// get relevant colors // get relevant colors
QColor base( client().backgroundColor( this, palette(), client().isActive() ) ); QColor base( _client->backgroundColor( this, palette(), _client->isActive() ) );
QColor light( client().helper().calcDarkColor( base ) ); QColor light( _client->helper().calcDarkColor( base ) );
QColor dark( client().helper().calcDarkColor( base.darker(150) ) ); QColor dark( _client->helper().calcDarkColor( base.darker(150) ) );
// create and configure painter // create and configure painter
QPainter painter(this); QPainter painter(this);
@ -190,10 +190,10 @@ namespace Oxygen
{ {
// check client window id // check client window id
if( !client().windowId() ) break; if( !_client->windowId() ) break;
client().widget()->setFocus(); _client->widget()->setFocus();
if( client().decoration() ) if( _client->decoration() )
{ client().decoration()->performWindowOperation( KDecorationDefines::ResizeOp ); } { _client->decoration()->performWindowOperation( KDecorationDefines::ResizeOp ); }
} }
break; break;
@ -211,24 +211,24 @@ namespace Oxygen
{ {
QPoint position( QPoint position(
client().width() - GRIP_SIZE - OFFSET, _client->width() - GRIP_SIZE - OFFSET,
client().height() - GRIP_SIZE - OFFSET ); _client->height() - GRIP_SIZE - OFFSET );
if( client().isPreview() ) if( _client->isPreview() )
{ {
position -= QPoint( position -= QPoint(
client().layoutMetric( Client::LM_BorderRight )+ _client->layoutMetric( Client::LM_BorderRight )+
client().layoutMetric( Client::LM_OuterPaddingRight ), _client->layoutMetric( Client::LM_OuterPaddingRight ),
client().layoutMetric( Client::LM_OuterPaddingBottom )+ _client->layoutMetric( Client::LM_OuterPaddingBottom )+
client().layoutMetric( Client::LM_BorderBottom ) _client->layoutMetric( Client::LM_BorderBottom )
); );
} else { } else {
position -= QPoint( position -= QPoint(
client().layoutMetric( Client::LM_BorderRight ), _client->layoutMetric( Client::LM_BorderRight ),
client().layoutMetric( Client::LM_BorderBottom ) ); _client->layoutMetric( Client::LM_BorderBottom ) );
} }
move( position ); move( position );