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)
if(X11_FOUND)
target_link_libraries(kwin3_oxygen ${X11_X11_LIB} ${XCB_XCB_LIBRARIES})
target_link_libraries(kwin3_oxygen Qt5::X11Extras)
target_link_libraries(kwin3_oxygen ${XCB_XCB_LIBRARIES})
endif()
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)
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)
endif()

View File

@ -38,10 +38,7 @@
#include <QPushButton>
#include <QX11Info>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <fixx11h.h>
#include <xcb/xcb.h>
namespace Oxygen
{
@ -49,7 +46,8 @@ namespace Oxygen
//_________________________________________________________
DetectDialog::DetectDialog( QWidget* parent ):
QDialog( parent ),
_grabber( 0 )
_grabber( 0 ),
_wmStateAtom( 0 )
{
// setup
@ -58,6 +56,13 @@ namespace Oxygen
connect( buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL(clicked()), this, SLOT(close()) );
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()
{
Window root;
Window child;
uint mask;
int rootX, rootY, x, y;
Window parent = reinterpret_cast<Window>( QX11Info::appRootWindow() );
Atom wm_state = XInternAtom( QX11Info::display(), "WM_STATE", False );
// check atom
if( !_wmStateAtom ) return 0;
xcb_connection_t* connection( QX11Info::connection() );
xcb_window_t parent( QX11Info::appRootWindow() );
// why is there a loop of only 10 here
for( int i = 0; i < 10; ++i )
{
XQueryPointer( QX11Info::display(), parent, &root, &child, &rootX, &rootY, &x, &y, &mask );
if( child == None ) return 0;
Atom type;
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 )
// query pointer
xcb_query_pointer_reply_t* pointerReply( 0x0 );
{
if( prop != NULL ) XFree( prop );
if( type != None ) return child;
xcb_query_pointer_cookie_t cookie( xcb_query_pointer( connection, parent ) );
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;

View File

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

View File

@ -43,13 +43,9 @@
#include <QLabel>
#include <QPainter>
#include <QBitmap>
#include <QX11Info>
#include <QObjectList>
#include <QMimeData>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
namespace Oxygen
{
@ -2042,9 +2038,9 @@ namespace Oxygen
// create atom
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 <QTimerEvent>
#include <X11/Xdefs.h>
#include <xcb/xcb.h>
namespace Oxygen
{
@ -485,7 +485,7 @@ namespace Oxygen
QBasicTimer _dragStartTimer;
//! shadow atom
Atom _shadowAtom;
xcb_atom_t _shadowAtom;
};

View File

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