Port Client's decoration resize extend input window to XCB
Using Xcb::Window to manage the xcb_window_t and simplify the code - no longer need to check whether the input_window is valid before calling e.g. map, as that's handled in Xcb::Window. One XLib usage for setting cursor is still present. This will be ported once all the QCursor::handle() get removed. REVIEW: 108771icc-effect-5.14.5
parent
3d5f962566
commit
74097e7d29
54
client.cpp
54
client.cpp
|
@ -141,7 +141,7 @@ Client::Client(Workspace* ws)
|
|||
#ifdef KWIN_BUILD_KAPPMENU
|
||||
, m_menuAvailable(false)
|
||||
#endif
|
||||
, input_window(None)
|
||||
, m_decoInputExtent()
|
||||
{
|
||||
// TODO: Do all as initialization
|
||||
#ifdef HAVE_XSYNC
|
||||
|
@ -385,10 +385,7 @@ void Client::updateInputWindow()
|
|||
}
|
||||
|
||||
if (region.isEmpty()) {
|
||||
if (input_window) {
|
||||
XDestroyWindow(display(), input_window);
|
||||
input_window = None;
|
||||
}
|
||||
m_decoInputExtent.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -401,23 +398,25 @@ void Client::updateInputWindow()
|
|||
// Move the region to input window coordinates
|
||||
region.translate(-input_offset);
|
||||
|
||||
if (!input_window) {
|
||||
XSetWindowAttributes attr;
|
||||
attr.event_mask = EnterWindowMask | LeaveWindowMask |
|
||||
ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
|
||||
attr.override_redirect = True;
|
||||
|
||||
input_window = XCreateWindow(display(), rootWindow(), bounds.x(), bounds.y(),
|
||||
bounds.width(), bounds.height(), 0, 0,
|
||||
InputOnly, 0, CWEventMask | CWOverrideRedirect, &attr);
|
||||
if (!m_decoInputExtent.isValid()) {
|
||||
const uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
|
||||
const uint32_t values[] = {true,
|
||||
XCB_EVENT_MASK_ENTER_WINDOW |
|
||||
XCB_EVENT_MASK_LEAVE_WINDOW |
|
||||
XCB_EVENT_MASK_BUTTON_PRESS |
|
||||
XCB_EVENT_MASK_BUTTON_RELEASE |
|
||||
XCB_EVENT_MASK_POINTER_MOTION
|
||||
};
|
||||
m_decoInputExtent.create(bounds, XCB_WINDOW_CLASS_INPUT_ONLY, mask, values);
|
||||
if (mapping_state == Mapped)
|
||||
XMapWindow(display(), inputId());
|
||||
m_decoInputExtent.map();
|
||||
} else {
|
||||
XMoveResizeWindow(display(), input_window, bounds.x(), bounds.y(),
|
||||
bounds.width(), bounds.height());
|
||||
m_decoInputExtent.setGeometry(bounds);
|
||||
}
|
||||
|
||||
XShapeCombineRegion(display(), input_window, ShapeInput, 0, 0, region.handle(), ShapeSet);
|
||||
const QVector<xcb_rectangle_t> rects = Xcb::regionToRects(region);
|
||||
xcb_shape_rectangles(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED,
|
||||
m_decoInputExtent, 0, 0, rects.count(), rects.constData());
|
||||
}
|
||||
|
||||
void Client::updateDecoration(bool check_workspace_pos, bool force)
|
||||
|
@ -484,10 +483,7 @@ void Client::destroyDecoration()
|
|||
emit geometryShapeChanged(this, oldgeom);
|
||||
}
|
||||
}
|
||||
if (inputId()) {
|
||||
XDestroyWindow(display(), input_window);
|
||||
input_window = None;
|
||||
}
|
||||
m_decoInputExtent.reset();
|
||||
}
|
||||
|
||||
bool Client::checkBorderSizes(bool also_resize)
|
||||
|
@ -1147,8 +1143,7 @@ void Client::internalShow(allowed_t)
|
|||
if (old == Unmapped || old == Withdrawn)
|
||||
map(Allowed);
|
||||
if (old == Kept) {
|
||||
if (inputId())
|
||||
XMapWindow(display(), inputId());
|
||||
m_decoInputExtent.map();
|
||||
updateHiddenPreview();
|
||||
}
|
||||
if (Compositor::isCreated()) {
|
||||
|
@ -1182,8 +1177,7 @@ void Client::internalKeep(allowed_t)
|
|||
mapping_state = Kept;
|
||||
if (old == Unmapped || old == Withdrawn)
|
||||
map(Allowed);
|
||||
if (inputId())
|
||||
XUnmapWindow(display(), inputId());
|
||||
m_decoInputExtent.unmap();
|
||||
updateHiddenPreview();
|
||||
addWorkspaceRepaint(visibleRect());
|
||||
workspace()->clientHidden(this);
|
||||
|
@ -1210,8 +1204,7 @@ void Client::map(allowed_t)
|
|||
if (!isShade()) {
|
||||
XMapWindow(display(), wrapper);
|
||||
XMapWindow(display(), client);
|
||||
if (inputId())
|
||||
XMapWindow(display(), inputId());
|
||||
m_decoInputExtent.map();
|
||||
exportMappingState(NormalState);
|
||||
} else
|
||||
exportMappingState(IconicState);
|
||||
|
@ -1232,8 +1225,7 @@ void Client::unmap(allowed_t)
|
|||
XUnmapWindow(display(), frameId());
|
||||
XUnmapWindow(display(), wrapper);
|
||||
XUnmapWindow(display(), client);
|
||||
if (inputId())
|
||||
XUnmapWindow(display(), inputId());
|
||||
m_decoInputExtent.unmap();
|
||||
XSelectInput(display(), wrapper, ClientWinMask | SubstructureNotifyMask);
|
||||
if (decoration != NULL)
|
||||
decoration->widget()->hide(); // Not really necessary, but let it know the state
|
||||
|
@ -2268,7 +2260,7 @@ void Client::updateCursor()
|
|||
if (decoration != NULL)
|
||||
decoration->widget()->setCursor(cursor);
|
||||
XDefineCursor(display(), frameId(), cursor.handle());
|
||||
if (inputId())
|
||||
if (m_decoInputExtent.isValid())
|
||||
XDefineCursor(display(), inputId(), cursor.handle());
|
||||
if (moveResizeMode) // XDefineCursor doesn't change cursor if there's pointer grab active
|
||||
XChangeActivePointerGrab(display(),
|
||||
|
|
5
client.h
5
client.h
|
@ -44,6 +44,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "rules.h"
|
||||
#include "toplevel.h"
|
||||
#include "tabgroup.h"
|
||||
#include "xcbutils.h"
|
||||
|
||||
#ifdef HAVE_XSYNC
|
||||
#include <X11/extensions/sync.h>
|
||||
|
@ -284,7 +285,7 @@ public:
|
|||
explicit Client(Workspace* ws);
|
||||
Window wrapperId() const;
|
||||
Window decorationId() const;
|
||||
Window inputId() const { return input_window; }
|
||||
xcb_window_t inputId() const { return m_decoInputExtent; }
|
||||
|
||||
const Client* transientFor() const;
|
||||
Client* transientFor();
|
||||
|
@ -995,7 +996,7 @@ private:
|
|||
#ifdef KWIN_BUILD_KAPPMENU
|
||||
bool m_menuAvailable;
|
||||
#endif
|
||||
Window input_window;
|
||||
Xcb::Window m_decoInputExtent;
|
||||
QPoint input_offset;
|
||||
};
|
||||
|
||||
|
|
|
@ -1892,10 +1892,7 @@ void Client::setGeometry(int x, int y, int w, int h, ForceGeometry_t force)
|
|||
}
|
||||
|
||||
// Unconditionally move the input window: it won't affect rendering
|
||||
if (inputId()) {
|
||||
const QPoint pos = QPoint(x, y) + inputPos();
|
||||
XMoveWindow(display(), inputId(), pos.x(), pos.y());
|
||||
}
|
||||
m_decoInputExtent.move(QPoint(x, y) + inputPos());
|
||||
}
|
||||
updateWindowRules(Rules::Position|Rules::Size);
|
||||
|
||||
|
|
39
xcbutils.h
39
xcbutils.h
|
@ -318,6 +318,8 @@ public:
|
|||
**/
|
||||
void setGeometry(const QRect &geometry);
|
||||
void setGeometry(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||
void move(const QPoint &pos);
|
||||
void move(uint32_t x, uint32_t y);
|
||||
void map();
|
||||
void unmap();
|
||||
/**
|
||||
|
@ -426,6 +428,23 @@ void Window::setGeometry(uint32_t x, uint32_t y, uint32_t width, uint32_t height
|
|||
xcb_configure_window(connection(), m_window, mask, values);
|
||||
}
|
||||
|
||||
inline
|
||||
void Window::move(const QPoint &pos)
|
||||
{
|
||||
move(pos.x(), pos.y());
|
||||
}
|
||||
|
||||
inline
|
||||
void Window::move(uint32_t x, uint32_t y)
|
||||
{
|
||||
if (!isValid()) {
|
||||
return;
|
||||
}
|
||||
const uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
|
||||
const uint32_t values[] = { x, y };
|
||||
xcb_configure_window(connection(), m_window, mask, values);
|
||||
}
|
||||
|
||||
inline
|
||||
void Window::map()
|
||||
{
|
||||
|
@ -530,6 +549,26 @@ static inline int defaultDepth()
|
|||
return depth;
|
||||
}
|
||||
|
||||
static inline xcb_rectangle_t fromQt(const QRect &rect)
|
||||
{
|
||||
xcb_rectangle_t rectangle;
|
||||
rectangle.x = rect.x();
|
||||
rectangle.y = rect.y();
|
||||
rectangle.width = rect.width();
|
||||
rectangle.height = rect.height();
|
||||
return rectangle;
|
||||
}
|
||||
|
||||
static inline QVector<xcb_rectangle_t> regionToRects(const QRegion ®ion)
|
||||
{
|
||||
const QVector<QRect> regionRects = region.rects();
|
||||
QVector<xcb_rectangle_t> rects(regionRects.count());
|
||||
for (int i=0; i<regionRects.count(); ++i) {
|
||||
rects[i] = Xcb::fromQt(regionRects.at(i));
|
||||
}
|
||||
return rects;
|
||||
}
|
||||
|
||||
} // namespace X11
|
||||
|
||||
} // namespace KWin
|
||||
|
|
Loading…
Reference in New Issue