Support for cursor change tracking in KWin::Cursor
KWin::Cursor can track changes to the cursor image. It supports a start/stop tracking to not handle these events if nobody is interested in them. When enabled and the cursor image changes a signal is emitted with the serial number of the new cursor image. To track cursor image changes xcb_xfixes_select_cursor_input is used (see XFixes Version 5.0 protocol, section 7). This could be useful for the zoom effect when it replaces the cursor. REVIEW: 110519icc-effect-5.14.5
parent
17e38f3357
commit
8b2a5f9936
47
cursor.cpp
47
cursor.cpp
|
@ -27,6 +27,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
// Xlib
|
// Xlib
|
||||||
#include <X11/Xcursor/Xcursor.h>
|
#include <X11/Xcursor/Xcursor.h>
|
||||||
#include <fixx11h.h>
|
#include <fixx11h.h>
|
||||||
|
// xcb
|
||||||
|
#include <xcb/xfixes.h>
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
@ -36,6 +38,7 @@ KWIN_SINGLETON_FACTORY_FACTORED(Cursor, X11Cursor)
|
||||||
Cursor::Cursor(QObject *parent)
|
Cursor::Cursor(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_mousePollingCounter(0)
|
, m_mousePollingCounter(0)
|
||||||
|
, m_cursorTrackingCounter(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +122,40 @@ void Cursor::doStopMousePolling()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cursor::startCursorTracking()
|
||||||
|
{
|
||||||
|
++m_cursorTrackingCounter;
|
||||||
|
if (m_cursorTrackingCounter == 1) {
|
||||||
|
doStartCursorTracking();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cursor::stopCursorTracking()
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_cursorTrackingCounter > 0);
|
||||||
|
--m_cursorTrackingCounter;
|
||||||
|
if (m_cursorTrackingCounter == 0) {
|
||||||
|
doStopCursorTracking();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cursor::doStartCursorTracking()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cursor::doStopCursorTracking()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cursor::notifyCursorChanged(uint32_t serial)
|
||||||
|
{
|
||||||
|
if (m_cursorTrackingCounter <= 0) {
|
||||||
|
// cursor change tracking is currently disabled, so don't emit signal
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit cursorChanged(serial);
|
||||||
|
}
|
||||||
|
|
||||||
X11Cursor::X11Cursor(QObject *parent)
|
X11Cursor::X11Cursor(QObject *parent)
|
||||||
: Cursor(parent)
|
: Cursor(parent)
|
||||||
, m_timeStamp(XCB_TIME_CURRENT_TIME)
|
, m_timeStamp(XCB_TIME_CURRENT_TIME)
|
||||||
|
@ -178,6 +215,16 @@ void X11Cursor::doStopMousePolling()
|
||||||
m_mousePollingTimer->stop();
|
m_mousePollingTimer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void X11Cursor::doStartCursorTracking()
|
||||||
|
{
|
||||||
|
xcb_xfixes_select_cursor_input(connection(), rootWindow(), XCB_XFIXES_CURSOR_NOTIFY_MASK_DISPLAY_CURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X11Cursor::doStopCursorTracking()
|
||||||
|
{
|
||||||
|
xcb_xfixes_select_cursor_input(connection(), rootWindow(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
void X11Cursor::mousePolled()
|
void X11Cursor::mousePolled()
|
||||||
{
|
{
|
||||||
const QPoint last = currentPos();
|
const QPoint last = currentPos();
|
||||||
|
|
51
cursor.h
51
cursor.h
|
@ -58,6 +58,34 @@ public:
|
||||||
virtual ~Cursor();
|
virtual ~Cursor();
|
||||||
void startMousePolling();
|
void startMousePolling();
|
||||||
void stopMousePolling();
|
void stopMousePolling();
|
||||||
|
/**
|
||||||
|
* @brief Enables tracking changes of cursor images.
|
||||||
|
*
|
||||||
|
* After enabling cursor change tracking the signal @link cursorChanged will be emitted
|
||||||
|
* whenever a change to the cursor image is recognized.
|
||||||
|
*
|
||||||
|
* Use @link stopCursorTracking to no longer emit this signal. Note: the signal will be
|
||||||
|
* emitted until each call of this method has been matched with a call to stopCursorTracking.
|
||||||
|
*
|
||||||
|
* This tracking is not about pointer position tracking.
|
||||||
|
* @see stopCursorTracking
|
||||||
|
* @see cursorChanged
|
||||||
|
*/
|
||||||
|
void startCursorTracking();
|
||||||
|
/**
|
||||||
|
* @brief Disables tracking changes of cursor images.
|
||||||
|
*
|
||||||
|
* Only call after using @link startCursorTracking.
|
||||||
|
*
|
||||||
|
* @see startCursorTracking
|
||||||
|
*/
|
||||||
|
void stopCursorTracking();
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* Called from X11 event handler.
|
||||||
|
*/
|
||||||
|
void notifyCursorChanged(uint32_t serial);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current cursor position. This method does an update of the mouse position if
|
* Returns the current cursor position. This method does an update of the mouse position if
|
||||||
|
@ -79,6 +107,16 @@ Q_SIGNALS:
|
||||||
void mouseChanged(const QPoint& pos, const QPoint& oldpos,
|
void mouseChanged(const QPoint& pos, const QPoint& oldpos,
|
||||||
Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons,
|
Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons,
|
||||||
Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers);
|
Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers);
|
||||||
|
/**
|
||||||
|
* @brief Signal emitted when the cursor image changes.
|
||||||
|
*
|
||||||
|
* To enable these signals use @link startCursorTracking.
|
||||||
|
*
|
||||||
|
* @param serial The serial number of the new selected cursor.
|
||||||
|
* @see startCursorTracking
|
||||||
|
* @see stopCursorTracking
|
||||||
|
*/
|
||||||
|
void cursorChanged(uint32_t serial);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
@ -106,6 +144,16 @@ protected:
|
||||||
* does nothing, inheriting classes can overwrite to e.g. stop a timer.
|
* does nothing, inheriting classes can overwrite to e.g. stop a timer.
|
||||||
**/
|
**/
|
||||||
virtual void doStopMousePolling();
|
virtual void doStopMousePolling();
|
||||||
|
/**
|
||||||
|
* Called from @link startCursorTracking when cursor image tracking gets activated. Inheriting class needs
|
||||||
|
* to overwrite to enable platform specific code for the tracking.
|
||||||
|
*/
|
||||||
|
virtual void doStartCursorTracking();
|
||||||
|
/**
|
||||||
|
* Called from @link stopCursorTracking when cursor image tracking gets deactivated. Inheriting class needs
|
||||||
|
* to overwrite to disable platform specific code for the tracking.
|
||||||
|
*/
|
||||||
|
virtual void doStopCursorTracking();
|
||||||
/**
|
/**
|
||||||
* Provides the actual internal cursor position to inheriting classes. If an inheriting class needs
|
* Provides the actual internal cursor position to inheriting classes. If an inheriting class needs
|
||||||
* access to the cursor position this method should be used instead of the static @link pos, as
|
* access to the cursor position this method should be used instead of the static @link pos, as
|
||||||
|
@ -122,6 +170,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
QPoint m_pos;
|
QPoint m_pos;
|
||||||
int m_mousePollingCounter;
|
int m_mousePollingCounter;
|
||||||
|
int m_cursorTrackingCounter;
|
||||||
|
|
||||||
KWIN_SINGLETON(Cursor)
|
KWIN_SINGLETON(Cursor)
|
||||||
};
|
};
|
||||||
|
@ -137,6 +186,8 @@ protected:
|
||||||
virtual void doGetPos();
|
virtual void doGetPos();
|
||||||
virtual void doStartMousePolling();
|
virtual void doStartMousePolling();
|
||||||
virtual void doStopMousePolling();
|
virtual void doStopMousePolling();
|
||||||
|
virtual void doStartCursorTracking();
|
||||||
|
virtual void doStopCursorTracking();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -54,6 +54,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <kkeyserver.h>
|
#include <kkeyserver.h>
|
||||||
|
|
||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
|
#include <X11/extensions/Xfixes.h>
|
||||||
#include <X11/extensions/Xrandr.h>
|
#include <X11/extensions/Xrandr.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <QX11Info>
|
#include <QX11Info>
|
||||||
|
@ -343,6 +344,8 @@ bool Workspace::workspaceEvent(XEvent * e)
|
||||||
foreach (Client * c, desktops)
|
foreach (Client * c, desktops)
|
||||||
c->syncEvent(reinterpret_cast< XSyncAlarmNotifyEvent* >(e));
|
c->syncEvent(reinterpret_cast< XSyncAlarmNotifyEvent* >(e));
|
||||||
#endif
|
#endif
|
||||||
|
} else if (e->type == Xcb::Extensions::self()->fixesCursorNotifyEvent() && Xcb::Extensions::self()->isFixesAvailable()) {
|
||||||
|
Cursor::self()->notifyCursorChanged(reinterpret_cast<XFixesCursorNotifyEvent*>(e)->cursor_serial);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ target_link_libraries( testClientMachine
|
||||||
${QT_QTCORE_LIBRARY}
|
${QT_QTCORE_LIBRARY}
|
||||||
${KDE4_KDEUI_LIBS}
|
${KDE4_KDEUI_LIBS}
|
||||||
${XCB_XCB_LIBRARIES}
|
${XCB_XCB_LIBRARIES}
|
||||||
|
${XCB_XFIXES_LIBRARIES}
|
||||||
${X11_XCB_LIBRARIES}
|
${X11_XCB_LIBRARIES}
|
||||||
${X11_X11_LIB} # to make jenkins happy
|
${X11_X11_LIB} # to make jenkins happy
|
||||||
${X11_Xcursor_LIB}
|
${X11_Xcursor_LIB}
|
||||||
|
|
|
@ -215,6 +215,11 @@ bool Extensions::isFixesRegionAvailable() const
|
||||||
return m_fixes.version >= 0x30; // 3
|
return m_fixes.version >= 0x30; // 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Extensions::fixesCursorNotifyEvent() const
|
||||||
|
{
|
||||||
|
return m_fixes.eventBase + XCB_XFIXES_CURSOR_NOTIFY;
|
||||||
|
}
|
||||||
|
|
||||||
bool Extensions::isShapeInputAvailable() const
|
bool Extensions::isShapeInputAvailable() const
|
||||||
{
|
{
|
||||||
return m_shape.version >= 0x11; // 1.1
|
return m_shape.version >= 0x11; // 1.1
|
||||||
|
|
|
@ -245,6 +245,7 @@ public:
|
||||||
bool isFixesAvailable() const {
|
bool isFixesAvailable() const {
|
||||||
return m_fixes.version > 0;
|
return m_fixes.version > 0;
|
||||||
}
|
}
|
||||||
|
int fixesCursorNotifyEvent() const;
|
||||||
bool isFixesRegionAvailable() const;
|
bool isFixesRegionAvailable() const;
|
||||||
bool isSyncAvailable() const {
|
bool isSyncAvailable() const {
|
||||||
return m_sync.present;
|
return m_sync.present;
|
||||||
|
|
Loading…
Reference in New Issue