Port Client's shape handling to XCB
REVIEW: 108772
This commit is contained in:
parent
4a0a4bc27e
commit
0348a14a7d
3 changed files with 69 additions and 47 deletions
95
client.cpp
95
client.cpp
|
@ -693,11 +693,12 @@ void Client::updateShape()
|
||||||
noborder = rules()->checkNoBorder(true);
|
noborder = rules()->checkNoBorder(true);
|
||||||
updateDecoration(true);
|
updateDecoration(true);
|
||||||
}
|
}
|
||||||
if (noBorder())
|
if (noBorder()) {
|
||||||
XShapeCombineShape(display(), frameId(), ShapeBounding,
|
xcb_shape_combine(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING,
|
||||||
clientPos().x(), clientPos().y(), window(), ShapeBounding, ShapeSet);
|
frameId(), clientPos().x(), clientPos().y(), window());
|
||||||
|
}
|
||||||
} else if (app_noborder) {
|
} else if (app_noborder) {
|
||||||
XShapeCombineMask(display(), frameId(), ShapeBounding, 0, 0, None, ShapeSet);
|
xcb_shape_mask(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, frameId(), 0, 0, XCB_PIXMAP_NONE);
|
||||||
detectNoBorder();
|
detectNoBorder();
|
||||||
app_noborder = noborder = rules()->checkNoBorder(noborder);
|
app_noborder = noborder = rules()->checkNoBorder(noborder);
|
||||||
updateDecoration(true);
|
updateDecoration(true);
|
||||||
|
@ -713,7 +714,7 @@ void Client::updateShape()
|
||||||
emit geometryShapeChanged(this, geometry());
|
emit geometryShapeChanged(this, geometry());
|
||||||
}
|
}
|
||||||
|
|
||||||
static Window shape_helper_window = None;
|
static Xcb::Window shape_helper_window(XCB_WINDOW_NONE);
|
||||||
|
|
||||||
void Client::updateInputShape()
|
void Client::updateInputShape()
|
||||||
{
|
{
|
||||||
|
@ -730,18 +731,18 @@ void Client::updateInputShape()
|
||||||
// until the real shape of the client is added and that can make
|
// until the real shape of the client is added and that can make
|
||||||
// the window lose focus (which is a problem with mouse focus policies)
|
// the window lose focus (which is a problem with mouse focus policies)
|
||||||
// TODO: It seems there is, after all - XShapeGetRectangles() - but maybe this is better
|
// TODO: It seems there is, after all - XShapeGetRectangles() - but maybe this is better
|
||||||
if (shape_helper_window == None)
|
if (!shape_helper_window.isValid())
|
||||||
shape_helper_window = XCreateSimpleWindow(display(), rootWindow(),
|
shape_helper_window.create(QRect(0, 0, 1, 1));
|
||||||
0, 0, 1, 1, 0, 0, 0);
|
shape_helper_window.resize(width(), height());
|
||||||
XResizeWindow(display(), shape_helper_window, width(), height());
|
xcb_connection_t *c = connection();
|
||||||
XShapeCombineShape(display(), shape_helper_window, ShapeInput, 0, 0,
|
xcb_shape_combine(c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_SHAPE_SK_BOUNDING,
|
||||||
frameId(), ShapeBounding, ShapeSet);
|
shape_helper_window, 0, 0, frameId());
|
||||||
XShapeCombineShape(display(), shape_helper_window, ShapeInput,
|
xcb_shape_combine(c, XCB_SHAPE_SO_SUBTRACT, XCB_SHAPE_SK_INPUT, XCB_SHAPE_SK_BOUNDING,
|
||||||
clientPos().x(), clientPos().y(), window(), ShapeBounding, ShapeSubtract);
|
shape_helper_window, clientPos().x(), clientPos().y(), window());
|
||||||
XShapeCombineShape(display(), shape_helper_window, ShapeInput,
|
xcb_shape_combine(c, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_INPUT, XCB_SHAPE_SK_INPUT,
|
||||||
clientPos().x(), clientPos().y(), window(), ShapeInput, ShapeUnion);
|
shape_helper_window, clientPos().x(), clientPos().y(), window());
|
||||||
XShapeCombineShape(display(), frameId(), ShapeInput, 0, 0,
|
xcb_shape_combine(c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_SHAPE_SK_INPUT,
|
||||||
shape_helper_window, ShapeInput, ShapeSet);
|
frameId(), 0, 0, shape_helper_window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,41 +752,41 @@ void Client::setMask(const QRegion& reg, int mode)
|
||||||
if (_mask == r)
|
if (_mask == r)
|
||||||
return;
|
return;
|
||||||
_mask = r;
|
_mask = r;
|
||||||
Window shape_window = frameId();
|
xcb_connection_t *c = connection();
|
||||||
|
xcb_window_t shape_window = frameId();
|
||||||
if (shape()) {
|
if (shape()) {
|
||||||
// The same way of applying a shape without strange intermediate states like above
|
// The same way of applying a shape without strange intermediate states like above
|
||||||
if (shape_helper_window == None)
|
if (!shape_helper_window.isValid())
|
||||||
shape_helper_window = XCreateSimpleWindow(display(), rootWindow(),
|
shape_helper_window.create(QRect(0, 0, 1, 1));
|
||||||
0, 0, 1, 1, 0, 0, 0);
|
|
||||||
shape_window = shape_helper_window;
|
shape_window = shape_helper_window;
|
||||||
}
|
}
|
||||||
if (_mask.isEmpty())
|
if (_mask.isEmpty()) {
|
||||||
XShapeCombineMask(display(), shape_window, ShapeBounding, 0, 0, None, ShapeSet);
|
xcb_shape_mask(c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, shape_window, 0, 0, XCB_PIXMAP_NONE);
|
||||||
else if (mode == X::Unsorted)
|
} else {
|
||||||
XShapeCombineRegion(display(), shape_window, ShapeBounding, 0, 0, _mask.handle(), ShapeSet);
|
const QVector< QRect > rects = _mask.rects();
|
||||||
else {
|
QVector< xcb_rectangle_t > xrects(rects.count());
|
||||||
QVector< QRect > rects = _mask.rects();
|
|
||||||
XRectangle* xrects = new XRectangle[rects.count()];
|
|
||||||
for (int i = 0; i < rects.count(); ++i) {
|
for (int i = 0; i < rects.count(); ++i) {
|
||||||
xrects[i].x = rects[i].x();
|
const QRect &rect = rects.at(i);
|
||||||
xrects[i].y = rects[i].y();
|
xcb_rectangle_t xrect;
|
||||||
xrects[i].width = rects[i].width();
|
xrect.x = rect.x();
|
||||||
xrects[i].height = rects[i].height();
|
xrect.y = rect.y();
|
||||||
|
xrect.width = rect.width();
|
||||||
|
xrect.height = rect.height();
|
||||||
|
xrects[i] = xrect;
|
||||||
}
|
}
|
||||||
XShapeCombineRectangles(display(), shape_window, ShapeBounding, 0, 0,
|
xcb_shape_rectangles(c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, mode, shape_window,
|
||||||
xrects, rects.count(), ShapeSet, mode);
|
0, 0, xrects.count(), xrects.constData());
|
||||||
delete[] xrects;
|
|
||||||
}
|
}
|
||||||
if (shape()) {
|
if (shape()) {
|
||||||
// The rest of the applyign using a temporary window
|
// The rest of the applying using a temporary window
|
||||||
XRectangle rec = { 0, 0, static_cast<unsigned short>(clientSize().width()),
|
xcb_rectangle_t rec = { 0, 0, static_cast<uint16_t>(clientSize().width()),
|
||||||
static_cast<unsigned short>(clientSize().height()) };
|
static_cast<uint16_t>(clientSize().height()) };
|
||||||
XShapeCombineRectangles(display(), shape_helper_window, ShapeBounding,
|
xcb_shape_rectangles(c, XCB_SHAPE_SO_SUBTRACT, XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED,
|
||||||
clientPos().x(), clientPos().y(), &rec, 1, ShapeSubtract, Unsorted);
|
shape_helper_window, clientPos().x(), clientPos().y(), 1, &rec);
|
||||||
XShapeCombineShape(display(), shape_helper_window, ShapeBounding,
|
xcb_shape_combine(c, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING,
|
||||||
clientPos().x(), clientPos().y(), window(), ShapeBounding, ShapeUnion);
|
shape_helper_window, clientPos().x(), clientPos().y(), window());
|
||||||
XShapeCombineShape(display(), frameId(), ShapeBounding, 0, 0,
|
xcb_shape_combine(c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING,
|
||||||
shape_helper_window, ShapeBounding, ShapeSet);
|
frameId(), 0, 0, shape_helper_window);
|
||||||
}
|
}
|
||||||
emit geometryShapeChanged(this, geometry());
|
emit geometryShapeChanged(this, geometry());
|
||||||
updateShape();
|
updateShape();
|
||||||
|
@ -1248,8 +1249,10 @@ void Client::updateHiddenPreview()
|
||||||
{
|
{
|
||||||
if (hiddenPreview()) {
|
if (hiddenPreview()) {
|
||||||
workspace()->forceRestacking();
|
workspace()->forceRestacking();
|
||||||
if (Xcb::Extensions::self()->isShapeInputAvailable())
|
if (Xcb::Extensions::self()->isShapeInputAvailable()) {
|
||||||
XShapeCombineRectangles(display(), frameId(), ShapeInput, 0, 0, NULL, 0, ShapeSet, Unsorted);
|
xcb_shape_rectangles(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT,
|
||||||
|
XCB_CLIP_ORDERING_UNSORTED, frameId(), 0, 0, 0, NULL);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
workspace()->forceRestacking();
|
workspace()->forceRestacking();
|
||||||
updateInputShape();
|
updateInputShape();
|
||||||
|
|
2
client.h
2
client.h
|
@ -438,7 +438,7 @@ public:
|
||||||
}
|
}
|
||||||
void demandAttention(bool set = true);
|
void demandAttention(bool set = true);
|
||||||
|
|
||||||
void setMask(const QRegion& r, int mode = X::Unsorted);
|
void setMask(const QRegion& r, int mode = XCB_CLIP_ORDERING_UNSORTED);
|
||||||
QRegion mask() const;
|
QRegion mask() const;
|
||||||
|
|
||||||
void updateDecoration(bool check_workspace_pos, bool force = false);
|
void updateDecoration(bool check_workspace_pos, bool force = false);
|
||||||
|
|
19
xcbutils.h
19
xcbutils.h
|
@ -335,6 +335,8 @@ public:
|
||||||
void setGeometry(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
void setGeometry(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||||
void move(const QPoint &pos);
|
void move(const QPoint &pos);
|
||||||
void move(uint32_t x, uint32_t y);
|
void move(uint32_t x, uint32_t y);
|
||||||
|
void resize(const QSize &size);
|
||||||
|
void resize(uint32_t width, uint32_t height);
|
||||||
void map();
|
void map();
|
||||||
void unmap();
|
void unmap();
|
||||||
/**
|
/**
|
||||||
|
@ -460,6 +462,23 @@ void Window::move(uint32_t x, uint32_t y)
|
||||||
xcb_configure_window(connection(), m_window, mask, values);
|
xcb_configure_window(connection(), m_window, mask, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void Window::resize(const QSize &size)
|
||||||
|
{
|
||||||
|
resize(size.width(), size.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void Window::resize(uint32_t width, uint32_t height)
|
||||||
|
{
|
||||||
|
if (!isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const uint16_t mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
|
||||||
|
const uint32_t values[] = { width, height };
|
||||||
|
xcb_configure_window(connection(), m_window, mask, values);
|
||||||
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void Window::map()
|
void Window::map()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue