21#include <xcb/composite.h>
37uint32_t KWIN_EXPORT
toXNative(qreal value);
38QRect KWIN_EXPORT
toXNative(
const QRectF &value);
50static void defineCursor(xcb_window_t window, xcb_cursor_t cursor);
51static void setInputFocus(xcb_window_t window, uint8_t revertTo = XCB_INPUT_FOCUS_POINTER_ROOT, xcb_timestamp_t time =
xTime());
52static void moveWindow(xcb_window_t window,
const QPoint &pos);
53static void moveWindow(xcb_window_t window, uint32_t x, uint32_t y);
54static void lowerWindow(xcb_window_t window);
55static void selectInput(xcb_window_t window, uint32_t events);
182template<
typename Reply,
207 typedef Reply *(*reply_func)(xcb_connection_t *, Cookie, xcb_generic_error_t **);
220template<
typename Reply,
228 typedef Reply *(*reply_func)(xcb_connection_t *, Cookie, xcb_generic_error_t **);
238template<
typename Data>
242 typedef typename Data::cookie_type
Cookie;
243 typedef typename Data::reply_type
Reply;
250 if (
this != &other) {
254 m_retrieved = other.m_retrieved;
255 m_cookie = other.m_cookie;
256 m_window = other.m_window;
257 m_reply = other.m_reply;
272 return m_reply ==
nullptr;
277 return m_reply == NULL;
279 inline operator bool()
283 inline operator bool()
const
315 Reply *ret = m_reply;
317 m_window = XCB_WINDOW_NONE;
324 , m_window(XCB_WINDOW_NONE)
327 m_cookie.sequence = 0;
337 : m_retrieved(other.m_retrieved)
338 , m_cookie(other.m_cookie)
339 , m_window(other.m_window)
346 if (m_retrieved || !m_cookie.sequence) {
349 m_reply = Data::replyFunc(
connection(), m_cookie,
nullptr);
354 inline void cleanup()
356 if (!m_retrieved && m_cookie.sequence) {
357 xcb_discard_reply(
connection(), m_cookie.sequence);
358 }
else if (m_reply) {
365 m_reply = other.take();
368 other.m_retrieved =
true;
369 other.m_window = XCB_WINDOW_NONE;
383template<
typename T1,
typename T2, std::
size_t I>
397template<
typename T1,
typename T2>
402 static constexpr bool value = std::is_same<tuple1Type, tuple2Type>::value;
408template<
typename Data,
typename... Args>
412 static_assert(!std::is_same<Data,
Xcb::WrapperData<
typename Data::reply_type,
typename Data::cookie_type, Args...>>::value,
413 "Data template argument must be derived from WrapperData");
414 static_assert(std::is_base_of<
Xcb::WrapperData<
typename Data::reply_type,
typename Data::cookie_type, Args...>, Data>::value,
415 "Data template argument must be derived from WrapperData");
416 static_assert(
sizeof...(Args) == Data::argumentCount,
417 "Wrapper and WrapperData need to have same template argument count");
418 static_assert(
tupleCompare<std::tuple<Args...>,
typename Data::argument_types,
sizeof...(Args) - 1>::value,
419 "Argument miss-match between Wrapper and WrapperData");
425 explicit Wrapper(xcb_window_t w, Args... args)
434template<
typename Data,
typename... Args>
438 static_assert(!std::is_same<Data,
Xcb::WrapperData<
typename Data::reply_type,
typename Data::cookie_type, xcb_window_t, Args...>>::value,
439 "Data template argument must be derived from WrapperData");
440 static_assert(std::is_base_of<
Xcb::WrapperData<
typename Data::reply_type,
typename Data::cookie_type, xcb_window_t, Args...>, Data>::value,
441 "Data template argument must be derived from WrapperData");
442 static_assert(
sizeof...(Args) + 1 == Data::argumentCount,
443 "Wrapper and WrapperData need to have same template argument count");
444 static_assert(
tupleCompare<std::tuple<xcb_window_t, Args...>,
typename Data::argument_types,
sizeof...(Args)>::value,
445 "Argument miss-match between Wrapper and WrapperData");
447 explicit Wrapper(xcb_window_t w, Args... args)
458template<
typename Data>
462 static_assert(!std::is_same<Data, Xcb::WrapperData<typename Data::reply_type, typename Data::cookie_type>>::value,
463 "Data template argument must be derived from WrapperData");
464 static_assert(std::is_base_of<Xcb::WrapperData<typename Data::reply_type, typename Data::cookie_type>, Data>::value,
465 "Data template argument must be derived from WrapperData");
466 static_assert(Data::argumentCount == 0,
"Wrapper for no arguments constructed with WrapperData with arguments");
479 , m_cookie(xcb_intern_atom_unchecked(m_connection, onlyIfExists,
name.length(),
name.constData()))
480 , m_atom(XCB_ATOM_NONE)
489 if (!m_retrieved && m_cookie.sequence) {
490 xcb_discard_reply(m_connection, m_cookie.sequence);
494 operator xcb_atom_t()
const
496 (
const_cast<Atom *
>(
this))->getReply();
502 return m_atom != XCB_ATOM_NONE;
506 (
const_cast<Atom *
>(
this))->getReply();
507 return m_atom != XCB_ATOM_NONE;
510 inline const QByteArray &
name()
const
517 if (m_retrieved || !m_cookie.sequence) {
522 m_atom = reply->atom;
528 xcb_connection_t *m_connection;
530 xcb_intern_atom_cookie_t m_cookie;
553#define XCB_WRAPPER_DATA(__NAME__, __REQUEST__, ...) \
554 struct __NAME__ : public WrapperData<__REQUEST__##_reply_t, __REQUEST__##_cookie_t, __VA_ARGS__> \
556 static constexpr request_func requestFunc = &__REQUEST__##_unchecked; \
557 static constexpr reply_func replyFunc = &__REQUEST__##_reply; \
572#define XCB_WRAPPER(__NAME__, __REQUEST__, ...) \
573 XCB_WRAPPER_DATA(__NAME__##Data, __REQUEST__, __VA_ARGS__) \
574 typedef Wrapper<__NAME__##Data, __VA_ARGS__> __NAME__;
576XCB_WRAPPER(WindowAttributes, xcb_get_window_attributes, xcb_window_t)
577XCB_WRAPPER(OverlayWindow, xcb_composite_get_overlay_window, xcb_window_t)
584 :
Wrapper<GeometryData, xcb_window_t>()
588 :
Wrapper<GeometryData, xcb_window_t>(window)
594 const xcb_get_geometry_reply_t *geometry = data();
603 const xcb_get_geometry_reply_t *geometry = data();
616 :
Wrapper<TreeData, xcb_window_t>(window)
622 if (isNull() || data()->children_len == 0) {
625 return xcb_query_tree_children(data());
630 return XCB_WINDOW_NONE;
632 return (*this)->parent;
636XCB_WRAPPER(Pointer, xcb_query_pointer, xcb_window_t)
640 static constexpr request_func requestFunc = &xcb_get_input_focus_unchecked;
641 static constexpr reply_func replyFunc = &xcb_get_input_focus_reply;
655 return XCB_WINDOW_NONE;
657 return (*this)->focus;
695 return xcb_get_modifier_mapping_keycodes(
data());
702 return xcb_get_modifier_mapping_keycodes_length(
data());
706XCB_WRAPPER_DATA(PropertyData, xcb_get_property, uint8_t, xcb_window_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t)
707class
Property : public
Wrapper<PropertyData, uint8_t, xcb_window_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t>
711 :
Wrapper<PropertyData, uint8_t, xcb_window_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t>()
712 , m_type(XCB_ATOM_NONE)
716 :
Wrapper<PropertyData, uint8_t, xcb_window_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t>(other)
717 , m_type(other.m_type)
720 explicit Property(uint8_t _delete, xcb_window_t window, xcb_atom_t property, xcb_atom_t
type, uint32_t long_offset, uint32_t long_length)
721 :
Wrapper<PropertyData, uint8_t, xcb_window_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t>(window, _delete, window, property,
type, long_offset, long_length)
728 m_type = other.m_type;
745 inline typename std::enable_if<!std::is_pointer<T>::value, T>
::type value(T defaultValue = T(),
bool *ok =
nullptr)
747 return value<T>(
sizeof(T) * 8, m_type, defaultValue, ok);
764 inline typename std::enable_if<!std::is_pointer<T>::value, T>
::type value(uint8_t
format, xcb_atom_t
type, T defaultValue = T(),
bool *ok =
nullptr)
766 T *reply = value<T *>(
format,
type,
nullptr, ok);
785 inline typename std::enable_if<std::is_pointer<T>::value, T>
::type value(T defaultValue =
nullptr,
bool *ok =
nullptr)
787 return value<T>(
sizeof(
typename std::remove_pointer<T>::type) * 8, m_type, defaultValue, ok);
808 inline typename std::enable_if<std::is_pointer<T>::value, T>
::type value(uint8_t
format, xcb_atom_t
type, T defaultValue =
nullptr,
bool *ok =
nullptr)
813 const PropertyData::reply_type *reply = data();
817 if (reply->type !=
type) {
820 if (reply->format !=
format) {
827 if (xcb_get_property_value_length(reply) == 0) {
831 return reinterpret_cast<T
>(xcb_get_property_value(reply));
840 bool valueOk =
false;
841 const char *reply = value<const char *>(
format,
type,
nullptr, &valueOk);
846 if (valueOk && !reply) {
847 return QByteArray(
"", 0);
848 }
else if (!valueOk) {
851 return QByteArray(reply, xcb_get_property_value_length(data()));
858 return toByteArray(8, m_type, ok);
876 inline bool toBool(uint8_t
format = 32, xcb_atom_t
type = XCB_ATOM_CARDINAL,
bool *ok =
nullptr)
878 bool *reply = value<bool *>(
format,
type,
nullptr, ok);
882 if (data()->value_len != 1) {
888 return reply[0] != 0;
895 return toBool(32, m_type, ok);
907 :
Property(false, w, p, XCB_ATOM_STRING, 0, 10000)
910 operator QByteArray()
920 :
Property(0,
window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 0, 1)
931 WindowId *windows = value<WindowId *>();
960 m_sizeHints =
nullptr;
961 m_hints = NormalHints(m_window);
965 m_sizeHints = m_hints.sizeHints();
1003 return QSize(INT_MAX, INT_MAX);
1005 const QSize size(std::max(m_sizeHints->
maxWidth, 1), std::max(m_sizeHints->
maxHeight, 1));
1036 return XCB_GRAVITY_NORTH_WEST;
1038 return xcb_gravity_t(m_sizeHints->
winGravity);
1043 return QSize(1, INT_MAX);
1051 return QSize(INT_MAX, 1);
1061 class NormalHints :
public Property
1092 explicit NormalHints()
1095 :
Property(0,
window, XCB_ATOM_WM_NORMAL_HINTS, XCB_ATOM_WM_SIZE_HINTS, 0, 18)
1098 inline SizeHints *sizeHints()
1100 return value<SizeHints *>(32, XCB_ATOM_WM_SIZE_HINTS,
nullptr);
1106 if (!m_window || !m_sizeHints) {
1109 return m_sizeHints->
flags & flag;
1111 xcb_window_t m_window = XCB_WINDOW_NONE;
1112 NormalHints m_hints;
1113 NormalHints::SizeHints *m_sizeHints =
nullptr;
1139 m_prop =
Property(0, m_window, m_atom, m_atom, 0, 5);
1143 m_hints = m_prop.
value<MwmHints *>(32, m_atom,
nullptr);
1147 if (!m_window || !m_hints) {
1150 return m_hints->flags & uint32_t(Hints::Decorations);
1157 return !m_hints->decorations;
1161 return testFunction(Functions::Resize);
1165 return testFunction(Functions::Move);
1169 return testFunction(Functions::Minimize);
1173 return testFunction(Functions::Maximize);
1177 return testFunction(Functions::Close);
1185 uint32_t decorations;
1190 Functions = (1L << 0),
1191 Decorations = (1L << 1)
1193 enum class Functions {
1197 Minimize = (1L << 3),
1198 Maximize = (1L << 4),
1201 bool testFunction(Functions flag)
const
1203 if (!m_window || !m_hints) {
1206 if (!(m_hints->flags & uint32_t(Hints::Functions))) {
1210 const bool set_value = ((m_hints->functions & uint32_t(Functions::All)) == 0);
1211 if (m_hints->functions & uint32_t(flag)) {
1216 xcb_window_t m_window = XCB_WINDOW_NONE;
1219 MwmHints *m_hints =
nullptr;
1224XCB_WRAPPER(ScreenInfo, xcb_randr_get_screen_info, xcb_window_t)
1226XCB_WRAPPER_DATA(ScreenResourcesData, xcb_randr_get_screen_resources, xcb_window_t)
1231 :
Wrapper<ScreenResourcesData, xcb_window_t>(window)
1240 return xcb_randr_get_screen_resources_crtcs(data());
1247 return xcb_randr_get_screen_resources_modes(data());
1254 return xcb_randr_get_screen_resources_names(data());
1263 :
Wrapper<CrtcGammaData, xcb_randr_crtc_t>(c)
1269 return xcb_randr_get_crtc_gamma_red(data());
1273 return xcb_randr_get_crtc_gamma_green(data());
1277 return xcb_randr_get_crtc_gamma_blue(data());
1281XCB_WRAPPER_DATA(CrtcInfoData, xcb_randr_get_crtc_info, xcb_randr_crtc_t, xcb_timestamp_t)
1287 explicit CrtcInfo(xcb_randr_crtc_t c, xcb_timestamp_t t)
1288 :
Wrapper<CrtcInfoData, xcb_randr_crtc_t, xcb_timestamp_t>(c, t)
1294 const CrtcInfoData::reply_type *info = data();
1295 if (!info || info->num_outputs == 0 || info->mode == XCB_NONE || info->status != XCB_RANDR_SET_CONFIG_SUCCESS) {
1298 return QRect(info->x, info->y, info->width, info->height);
1302 const CrtcInfoData::reply_type *info = data();
1303 if (!info || info->num_outputs == 0 || info->mode == XCB_NONE || info->status != XCB_RANDR_SET_CONFIG_SUCCESS) {
1306 return xcb_randr_get_crtc_info_outputs(info);
1310XCB_WRAPPER_DATA(OutputInfoData, xcb_randr_get_output_info, xcb_randr_output_t, xcb_timestamp_t)
1317 :
Wrapper<OutputInfoData, xcb_randr_output_t, xcb_timestamp_t>(c, t)
1323 const OutputInfoData::reply_type *info = data();
1324 if (!info || info->num_crtcs == 0 || info->num_modes == 0 || info->status != XCB_RANDR_SET_CONFIG_SUCCESS) {
1327 return QString::fromUtf8(
reinterpret_cast<char *
>(xcb_randr_get_output_info_name(info)), info->name_len);
1331XCB_WRAPPER_DATA(CurrentResourcesData, xcb_randr_get_screen_resources_current, xcb_window_t)
1336 :
Wrapper<CurrentResourcesData, xcb_window_t>(window)
1345 return xcb_randr_get_screen_resources_current_crtcs(data());
1352 return xcb_randr_get_screen_resources_current_modes(data());
1356XCB_WRAPPER(SetCrtcConfig, xcb_randr_set_crtc_config, xcb_randr_crtc_t, xcb_timestamp_t, xcb_timestamp_t, int16_t, int16_t, xcb_randr_mode_t, uint16_t, uint32_t,
const xcb_randr_output_t *)
1358XCB_WRAPPER_DATA(OutputPropertyData, xcb_randr_get_output_property, xcb_randr_output_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t, uint8_t, uint8_t)
1363class
OutputProperty : public
Wrapper<OutputPropertyData, xcb_randr_output_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t, uint8_t, uint8_t>
1367 explicit OutputProperty(xcb_randr_output_t output, xcb_atom_t property, xcb_atom_t
type, uint32_t offset, uint32_t length, uint8_t _delete, uint8_t pending)
1368 :
Wrapper(output, property,
type, offset, length, _delete, pending)
1372 template<
typename T>
1373 inline typename std::enable_if<!std::is_pointer<T>::value, T>
::type value(T defaultValue = T(),
bool *ok =
nullptr)
1375 T *reply = value<T *>(
sizeof(T) * 8, m_type,
nullptr, ok);
1377 return defaultValue;
1381 template<
typename T>
1382 inline typename std::enable_if<std::is_pointer<T>::value, T>
::type value(T defaultValue =
nullptr,
bool *ok =
nullptr)
1384 return value<T>(
sizeof(
typename std::remove_pointer<T>::type) * 8, m_type, defaultValue, ok);
1386 template<
typename T>
1387 inline typename std::enable_if<std::is_pointer<T>::value, T>
::type value(uint8_t
format, xcb_atom_t
type, T defaultValue =
nullptr,
bool *ok =
nullptr)
1392 const OutputPropertyData::reply_type *reply = data();
1394 return defaultValue;
1396 if (reply->type !=
type) {
1397 return defaultValue;
1399 if (reply->format !=
format) {
1400 return defaultValue;
1406 if (xcb_randr_get_output_property_data_length(reply) == 0) {
1407 return defaultValue;
1410 return reinterpret_cast<T
>(xcb_randr_get_output_property_data(reply));
1414 bool valueOk =
false;
1415 const char *reply = value<const char *>(
format,
type,
nullptr, &valueOk);
1420 if (valueOk && !reply) {
1421 return QByteArray(
"", 0);
1422 }
else if (!valueOk) {
1423 return QByteArray();
1425 return QByteArray(reply, xcb_randr_get_output_property_data_length(data()));
1429 return toByteArray(8, m_type, ok);
1431 inline bool toBool(uint8_t
format = 32, xcb_atom_t
type = XCB_ATOM_CARDINAL,
bool *ok =
nullptr)
1433 bool *reply = value<bool *>(
format,
type,
nullptr, ok);
1437 if (data()->length != 1) {
1443 return reply[0] != 0;
1447 return toBool(32, m_type, ok);
1474 return m_shape.version > 0;
1476 bool isShapeInputAvailable()
const;
1477 int shapeNotifyEvent()
const;
1478 bool hasShape(xcb_window_t w)
const;
1481 return m_randr.present;
1483 int randrNotifyEvent()
const;
1486 return m_damage.present;
1488 int damageNotifyEvent()
const;
1491 return m_composite.version > 0;
1493 bool isCompositeOverlayAvailable()
const;
1496 return m_render.version > 0;
1500 return m_fixes.version > 0;
1502 int fixesCursorNotifyEvent()
const;
1503 int fixesSelectionNotifyEvent()
const;
1504 bool isFixesRegionAvailable()
const;
1507 return m_sync.present;
1509 int syncAlarmNotifyEvent()
const;
1510 QList<ExtensionData> extensions()
const;
1513 return m_glx.present;
1517 return m_glx.eventBase;
1521 return m_glx.majorOpcode;
1525 static void destroy();
1531 template<
typename reply,
typename T,
typename F>
1533 void extensionQueryReply(
const xcb_query_extension_reply_t *extension,
ExtensionData *dataToFill);
1571 Window(xcb_window_t window = XCB_WINDOW_NONE,
bool destroy =
true);
1580 Window(
const QRectF &
geometry, uint32_t mask = 0,
const uint32_t *values =
nullptr, xcb_window_t parent =
rootWindow());
1590 Window(
const QRectF &
geometry, uint16_t windowClass, uint32_t mask = 0,
const uint32_t *values =
nullptr, xcb_window_t parent =
rootWindow());
1604 void create(
const QRectF &
geometry, uint32_t mask = 0,
const uint32_t *values =
nullptr, xcb_window_t parent =
rootWindow());
1616 void create(
const QRectF &
geometry, uint16_t windowClass, uint32_t mask = 0,
const uint32_t *values =
nullptr, xcb_window_t parent =
rootWindow());
1623 void reset(xcb_window_t window = XCB_WINDOW_NONE,
bool destroy =
true);
1630 return m_logicGeometry;
1637 void setGeometry(qreal x, qreal y, qreal width, qreal height);
1638 void move(
const QPointF &pos);
1639 void move(qreal x, qreal y);
1640 void resize(
const QSizeF &size);
1641 void resize(qreal width, qreal height);
1646 void reparent(xcb_window_t parent, qreal x = 0, qreal y = 0);
1648 const void *data, uint8_t mode = XCB_PROP_MODE_REPLACE);
1651 void grabButton(uint8_t pointerMode, uint8_t keyboardmode,
1652 uint16_t modifiers = XCB_MOD_MASK_ANY,
1653 uint8_t button = XCB_BUTTON_INDEX_ANY,
1654 uint16_t eventMask = XCB_EVENT_MASK_BUTTON_PRESS,
1655 xcb_window_t confineTo = XCB_WINDOW_NONE,
1656 xcb_cursor_t cursor = XCB_CURSOR_NONE,
1657 bool ownerEvents =
false);
1658 void ungrabButton(uint16_t modifiers = XCB_MOD_MASK_ANY, uint8_t button = XCB_BUTTON_INDEX_ANY);
1665 void focus(uint8_t revertTo = XCB_INPUT_FOCUS_POINTER_ROOT, xcb_timestamp_t time = XCB_TIME_CURRENT_TIME);
1668 operator xcb_window_t()
const;
1671 xcb_window_t doCreate(
const QRectF &
geometry, uint16_t windowClass, uint32_t mask = 0,
const uint32_t *values =
nullptr, xcb_window_t parent =
rootWindow());
1673 xcb_window_t m_window;
1675 QRectF m_logicGeometry;
1680 , m_destroy(destroy)
1684inline Window::Window(
const QRectF &geometry, uint32_t mask,
const uint32_t *values, xcb_window_t parent)
1685 : m_window(doCreate(geometry, XCB_COPY_FROM_PARENT, mask, values, parent))
1690inline Window::Window(
const QRectF &geometry, uint16_t windowClass, uint32_t mask,
const uint32_t *values, xcb_window_t parent)
1691 : m_window(doCreate(geometry, windowClass, mask, values, parent))
1701inline void Window::destroy()
1703 if (!
isValid() || !m_destroy) {
1707 m_window = XCB_WINDOW_NONE;
1712 return m_window != XCB_WINDOW_NONE;
1715inline Window::operator xcb_window_t()
const
1720inline void Window::create(
const QRectF &geometry, uint16_t windowClass, uint32_t mask,
const uint32_t *values, xcb_window_t parent)
1723 m_window = doCreate(
geometry, windowClass, mask, values, parent);
1726inline void Window::create(
const QRectF &geometry, uint32_t mask,
const uint32_t *values, xcb_window_t parent)
1731inline xcb_window_t Window::doCreate(
const QRectF &geometry, uint16_t windowClass, uint32_t mask,
const uint32_t *values, xcb_window_t parent)
1734 xcb_window_t w = xcb_generate_id(
connection());
1735 xcb_create_window(
connection(), XCB_COPY_FROM_PARENT, w, parent,
1737 0, windowClass, XCB_COPY_FROM_PARENT, mask, values);
1745 m_destroy = shouldDestroy;
1755 m_logicGeometry.setRect(x, y, width, height);
1759 const uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
1761 xcb_configure_window(
connection(), m_window, mask, values);
1766 move(pos.x(), pos.y());
1771 m_logicGeometry.moveTo(x, y);
1775 moveWindow(m_window, x, y);
1780 resize(size.width(), size.height());
1785 m_logicGeometry.setSize(QSizeF(width, height));
1789 const uint16_t mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
1791 xcb_configure_window(
connection(), m_window, mask, values);
1796 const uint32_t values[] = {XCB_STACK_MODE_ABOVE};
1797 xcb_configure_window(
connection(), m_window, XCB_CONFIG_WINDOW_STACK_MODE, values);
1802 lowerWindow(m_window);
1842 xcb_delete_property(
connection(), m_window, property);
1851 xcb_configure_window(
connection(), m_window, XCB_CONFIG_WINDOW_BORDER_WIDTH, &_width);
1855 uint8_t button, uint16_t eventMask, xcb_window_t confineTo,
1856 xcb_cursor_t cursor,
bool ownerEvents)
1861 xcb_grab_button(
connection(), ownerEvents, m_window, eventMask,
1862 pointerMode, keyboardmode, confineTo, cursor, button, modifiers);
1870 xcb_ungrab_button(
connection(), button, m_window, modifiers);
1878 xcb_clear_area(
connection(),
false, m_window, 0, 0, 0, 0);
1886 const uint32_t values[] = {pixmap};
1887 xcb_change_window_attributes(
connection(), m_window, XCB_CW_BACK_PIXMAP, values);
1892 Xcb::defineCursor(m_window, cursor);
1897 setInputFocus(m_window, revertTo, time);
1902 Xcb::selectInput(m_window, events);
1911static inline void moveResizeWindow(
WindowId window,
const QRect &geometry)
1913 const uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
1916 xcb_configure_window(
connection(), window, mask, values);
1919static inline void moveWindow(xcb_window_t window,
const QPoint &pos)
1921 moveWindow(window, pos.x(), pos.y());
1924static inline void moveWindow(xcb_window_t window, uint32_t x, uint32_t y)
1926 const uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
1928 xcb_configure_window(
connection(), window, mask, values);
1931static inline void lowerWindow(xcb_window_t window)
1933 const uint32_t values[] = {XCB_STACK_MODE_BELOW};
1934 xcb_configure_window(
connection(), window, XCB_CONFIG_WINDOW_STACK_MODE, values);
1937static inline WindowId createInputWindow(
const QRect &geometry, uint32_t mask,
const uint32_t *values)
1941 geometry.x(), geometry.y(), geometry.width(), geometry.height(),
1942 0, XCB_WINDOW_CLASS_INPUT_ONLY,
1943 XCB_COPY_FROM_PARENT, mask, values);
1947static inline void restackWindows(
const QList<xcb_window_t> &windows)
1949 if (windows.count() < 2) {
1953 for (
int i = 1; i < windows.count(); ++i) {
1954 const uint16_t mask = XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE;
1955 const uint32_t stackingValues[] = {
1957 XCB_STACK_MODE_BELOW};
1958 xcb_configure_window(
connection(), windows.at(i), mask, stackingValues);
1962static inline void restackWindowsWithRaise(
const QList<xcb_window_t> &windows)
1964 if (windows.isEmpty()) {
1967 const uint32_t values[] = {XCB_STACK_MODE_ABOVE};
1968 xcb_configure_window(
connection(), windows.first(), XCB_CONFIG_WINDOW_STACK_MODE, values);
1969 restackWindows(windows);
1972static xcb_screen_t *defaultScreen()
1974 return xcb_setup_roots_iterator(xcb_get_setup(
connection())).data;
1977static inline int defaultDepth()
1979 return defaultScreen()->root_depth;
1982static inline xcb_rectangle_t fromQt(
const QRect &rect)
1984 const QRect nativeRect =
toXNative(rect);
1985 xcb_rectangle_t rectangle;
1986 rectangle.x = nativeRect.x();
1987 rectangle.y = nativeRect.y();
1988 rectangle.width = nativeRect.width();
1989 rectangle.height = nativeRect.height();
1993static inline QList<xcb_rectangle_t> regionToRects(
const QRegion ®ion)
1995 QList<xcb_rectangle_t> rects;
1996 rects.reserve(region.rectCount());
1997 for (
const QRect &rect : region) {
1998 rects.append(Xcb::fromQt(rect));
2003static inline void defineCursor(xcb_window_t window, xcb_cursor_t cursor)
2005 xcb_change_window_attributes(
connection(), window, XCB_CW_CURSOR, &cursor);
2008static inline void setInputFocus(xcb_window_t window, uint8_t revertTo, xcb_timestamp_t time)
2010 xcb_set_input_focus(
connection(), revertTo, window, time);
2013static inline void setTransientFor(xcb_window_t window, xcb_window_t transient_for_window)
2015 xcb_change_property(
connection(), XCB_PROP_MODE_REPLACE, window, XCB_ATOM_WM_TRANSIENT_FOR,
2016 XCB_ATOM_WINDOW, 32, 1, &transient_for_window);
2019static inline void sync()
2022 const auto cookie = xcb_get_input_focus(c);
2023 xcb_generic_error_t *error =
nullptr;
2024 UniqueCPtr<xcb_get_input_focus_reply_t> sync(xcb_get_input_focus_reply(c, cookie, &error));
2030void selectInput(xcb_window_t window, uint32_t events)
2032 xcb_change_window_attributes(
connection(), window, XCB_CW_EVENT_MASK, &events);
2045 xcb_shm_seg_t
segment()
const;
2053 xcb_shm_seg_t m_segment;
2055 uint8_t m_pixmapFormat;
2080 return m_pixmapFormat;
2083inline static Version xServerVersion()
2086 auto setup = xcb_get_setup(c);
2087 const QByteArray vendorName(xcb_setup_vendor(setup), xcb_setup_vendor_length(setup));
2088 if (vendorName.contains(
"X.Org")) {
2089 const int release = setup->release_number;
2090 return Version(release / 10000000, (release / 100000) % 100, (release / 1000) % 100);
2093 return Version(0, 0, 0);
Abstract base class for the wrapper.
AbstractWrapper(WindowId window, Cookie cookie)
const Reply * data() const
virtual ~AbstractWrapper()
const Reply * operator->()
AbstractWrapper(const AbstractWrapper &other)
AbstractWrapper & operator=(const AbstractWrapper &other)
Atom(const QByteArray &name, bool onlyIfExists=false, xcb_connection_t *c=connection())
Atom(const Atom &)=delete
const QByteArray & name() const
QList< QByteArray > errorCodes
QList< QByteArray > opCodes
bool isShapeAvailable() const
bool isCompositeAvailable() const
int glxMajorOpcode() const
bool isSyncAvailable() const
bool isRandrAvailable() const
bool isRenderAvailable() const
bool isDamageAvailable() const
bool isFixesAvailable() const
xcb_gravity_t windowGravity() const
void init(xcb_window_t window)
QSizeF resizeIncrements() const
bool hasResizeIncrements() const
bool hasWindowGravity() const
xcb_keycode_t * keycodes()
MotifHints(xcb_atom_t atom)
bool hasDecoration() const
void init(xcb_window_t window)
QByteArray toByteArray(uint8_t format=8, xcb_atom_t type=XCB_ATOM_STRING, bool *ok=nullptr)
Reads the property as string and returns a QByteArray.
Property(uint8_t _delete, xcb_window_t window, xcb_atom_t property, xcb_atom_t type, uint32_t long_offset, uint32_t long_length)
QByteArray toByteArray(bool *ok)
Overloaded method for convenience.
Property(const Property &other)
std::enable_if< std::is_pointer< T >::value, T >::type value(uint8_t format, xcb_atom_t type, T defaultValue=nullptr, bool *ok=nullptr)
Reads the property as an array of T.
std::enable_if<!std::is_pointer< T >::value, T >::type value(uint8_t format, xcb_atom_t type, T defaultValue=T(), bool *ok=nullptr)
Reads the property as a POD type.
bool toBool(bool *ok)
Overloaded method for convenience.
std::enable_if<!std::is_pointer< T >::value, T >::type value(T defaultValue=T(), bool *ok=nullptr)
Overloaded method for convenience.
bool toBool(uint8_t format=32, xcb_atom_t type=XCB_ATOM_CARDINAL, bool *ok=nullptr)
Reads the property as a boolean value.
Property & operator=(const Property &other)
std::enable_if< std::is_pointer< T >::value, T >::type value(T defaultValue=nullptr, bool *ok=nullptr)
Overloaded method for convenience.
CrtcGamma(xcb_randr_crtc_t c)
CrtcInfo(const CrtcInfo &)=default
xcb_randr_output_t * outputs()
CrtcInfo(xcb_randr_crtc_t c, xcb_timestamp_t t)
xcb_randr_mode_info_t * modes()
CurrentResources(WindowId window)
xcb_randr_crtc_t * crtcs()
OutputInfo(xcb_randr_output_t c, xcb_timestamp_t t)
OutputInfo(const OutputInfo &)=default
bool toBool(uint8_t format=32, xcb_atom_t type=XCB_ATOM_CARDINAL, bool *ok=nullptr)
std::enable_if< std::is_pointer< T >::value, T >::type value(uint8_t format, xcb_atom_t type, T defaultValue=nullptr, bool *ok=nullptr)
QByteArray toByteArray(bool *ok)
QByteArray toByteArray(uint8_t format=8, xcb_atom_t type=XCB_ATOM_STRING, bool *ok=nullptr)
std::enable_if< std::is_pointer< T >::value, T >::type value(T defaultValue=nullptr, bool *ok=nullptr)
OutputProperty(xcb_randr_output_t output, xcb_atom_t property, xcb_atom_t type, uint32_t offset, uint32_t length, uint8_t _delete, uint8_t pending)
std::enable_if<!std::is_pointer< T >::value, T >::type value(T defaultValue=T(), bool *ok=nullptr)
xcb_randr_crtc_t * crtcs()
ScreenResources(WindowId window)
xcb_randr_mode_info_t * modes()
Small helper class to encapsulate SHM related functionality.
uint8_t pixmapFormat() const
xcb_shm_seg_t segment() const
StringProperty(xcb_window_t w, xcb_atom_t p)
bool getTransientFor(WindowId *prop)
Fill given window pointer with the WM_TRANSIENT_FOR property of a window.
TransientFor(WindowId window)
WindowGeometry(xcb_window_t window)
const QRectF & geometry() const
void setBorderWidth(uint32_t width)
void deleteProperty(xcb_atom_t property)
void resize(const QSizeF &size)
void grabButton(uint8_t pointerMode, uint8_t keyboardmode, uint16_t modifiers=XCB_MOD_MASK_ANY, uint8_t button=XCB_BUTTON_INDEX_ANY, uint16_t eventMask=XCB_EVENT_MASK_BUTTON_PRESS, xcb_window_t confineTo=XCB_WINDOW_NONE, xcb_cursor_t cursor=XCB_CURSOR_NONE, bool ownerEvents=false)
void reparent(xcb_window_t parent, qreal x=0, qreal y=0)
void defineCursor(xcb_cursor_t cursor)
void changeProperty(xcb_atom_t property, xcb_atom_t type, uint8_t format, uint32_t length, const void *data, uint8_t mode=XCB_PROP_MODE_REPLACE)
Window(const Window &other)=delete
void ungrabButton(uint16_t modifiers=XCB_MOD_MASK_ANY, uint8_t button=XCB_BUTTON_INDEX_ANY)
void create(const QRectF &geometry, uint32_t mask=0, const uint32_t *values=nullptr, xcb_window_t parent=rootWindow())
void selectInput(uint32_t events)
void setGeometry(const QRectF &geometry)
Window(xcb_window_t window=XCB_WINDOW_NONE, bool destroy=true)
void reset(xcb_window_t window=XCB_WINDOW_NONE, bool destroy=true)
void focus(uint8_t revertTo=XCB_INPUT_FOCUS_POINTER_ROOT, xcb_timestamp_t time=XCB_TIME_CURRENT_TIME)
void move(const QPointF &pos)
void setBackgroundPixmap(xcb_pixmap_t pixmap)
Wrapper(xcb_window_t w, Args... args)
Wrapper taking a WrapperData as first template argument and xcb request args as variadic args.
Wrapper(xcb_window_t w, Args... args)
qreal fromXNative(int value)
uint32_t toXNative(qreal value)
QRectF nativeFloor(const QRectF &rect)
KWIN_EXPORT xcb_window_t rootWindow()
KWIN_EXPORT xcb_timestamp_t xTime()
KWIN_EXPORT xcb_connection_t * connection()
std::unique_ptr< T, CDeleter > UniqueCPtr
static constexpr reply_func replyFunc
static constexpr request_func requestFunc
static constexpr reply_func replyFunc
static constexpr request_func requestFunc
std::tuple argument_types
Variadic template to wrap an xcb request.
Cookie cookie_type
The type returned by the xcb request function.
Reply reply_type
The type returned by the xcb reply function.
xcb_query_keymap_reply_t *(* reply_func)(xcb_connection_t *, xcb_query_keymap_cookie_t, xcb_generic_error_t **)
The function pointer definition for the xcb reply function.
Cookie(* request_func)(xcb_connection_t *, Args...)
The function pointer definition for the xcb request function.
static constexpr std::size_t argumentCount
Number of variadic arguments.
std::tuple< Args... > argument_types
Variadic arguments combined as a std::tuple.
std::tuple_element< 0, T1 >::type tuple1Type
std::tuple_element< 0, T2 >::type tuple2Type
Template to compare the arguments of two std::tuple.
static constexpr bool value
std::tuple_element< I, T2 >::type tuple2Type
std::tuple_element< I, T1 >::type tuple1Type
#define XCB_WRAPPER_DATA(__NAME__, __REQUEST__,...)
Macro to create the WrapperData subclass.
#define XCB_WRAPPER(__NAME__, __REQUEST__,...)
Macro to create Wrapper typedef and WrapperData.