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
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#include <fixx11h.h>
|
||||
// xcb
|
||||
#include <xcb/xfixes.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -36,6 +38,7 @@ KWIN_SINGLETON_FACTORY_FACTORED(Cursor, X11Cursor)
|
|||
Cursor::Cursor(QObject *parent)
|
||||
: QObject(parent)
|
||||
, 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)
|
||||
: Cursor(parent)
|
||||
, m_timeStamp(XCB_TIME_CURRENT_TIME)
|
||||
|
@ -178,6 +215,16 @@ void X11Cursor::doStopMousePolling()
|
|||
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()
|
||||
{
|
||||
const QPoint last = currentPos();
|
||||
|
|
51
cursor.h
51
cursor.h
|
@ -58,6 +58,34 @@ public:
|
|||
virtual ~Cursor();
|
||||
void startMousePolling();
|
||||
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
|
||||
|
@ -79,6 +107,16 @@ Q_SIGNALS:
|
|||
void mouseChanged(const QPoint& pos, const QPoint& oldpos,
|
||||
Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons,
|
||||
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:
|
||||
/**
|
||||
|
@ -106,6 +144,16 @@ protected:
|
|||
* does nothing, inheriting classes can overwrite to e.g. stop a timer.
|
||||
**/
|
||||
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
|
||||
* access to the cursor position this method should be used instead of the static @link pos, as
|
||||
|
@ -122,6 +170,7 @@ protected:
|
|||
private:
|
||||
QPoint m_pos;
|
||||
int m_mousePollingCounter;
|
||||
int m_cursorTrackingCounter;
|
||||
|
||||
KWIN_SINGLETON(Cursor)
|
||||
};
|
||||
|
@ -137,6 +186,8 @@ protected:
|
|||
virtual void doGetPos();
|
||||
virtual void doStartMousePolling();
|
||||
virtual void doStopMousePolling();
|
||||
virtual void doStartCursorTracking();
|
||||
virtual void doStopCursorTracking();
|
||||
|
||||
private slots:
|
||||
/**
|
||||
|
|
|
@ -54,6 +54,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <kkeyserver.h>
|
||||
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <QX11Info>
|
||||
|
@ -343,6 +344,8 @@ bool Workspace::workspaceEvent(XEvent * e)
|
|||
foreach (Client * c, desktops)
|
||||
c->syncEvent(reinterpret_cast< XSyncAlarmNotifyEvent* >(e));
|
||||
#endif
|
||||
} else if (e->type == Xcb::Extensions::self()->fixesCursorNotifyEvent() && Xcb::Extensions::self()->isFixesAvailable()) {
|
||||
Cursor::self()->notifyCursorChanged(reinterpret_cast<XFixesCursorNotifyEvent*>(e)->cursor_serial);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ target_link_libraries( testClientMachine
|
|||
${QT_QTCORE_LIBRARY}
|
||||
${KDE4_KDEUI_LIBS}
|
||||
${XCB_XCB_LIBRARIES}
|
||||
${XCB_XFIXES_LIBRARIES}
|
||||
${X11_XCB_LIBRARIES}
|
||||
${X11_X11_LIB} # to make jenkins happy
|
||||
${X11_Xcursor_LIB}
|
||||
|
|
|
@ -215,6 +215,11 @@ bool Extensions::isFixesRegionAvailable() const
|
|||
return m_fixes.version >= 0x30; // 3
|
||||
}
|
||||
|
||||
int Extensions::fixesCursorNotifyEvent() const
|
||||
{
|
||||
return m_fixes.eventBase + XCB_XFIXES_CURSOR_NOTIFY;
|
||||
}
|
||||
|
||||
bool Extensions::isShapeInputAvailable() const
|
||||
{
|
||||
return m_shape.version >= 0x11; // 1.1
|
||||
|
|
|
@ -245,6 +245,7 @@ public:
|
|||
bool isFixesAvailable() const {
|
||||
return m_fixes.version > 0;
|
||||
}
|
||||
int fixesCursorNotifyEvent() const;
|
||||
bool isFixesRegionAvailable() const;
|
||||
bool isSyncAvailable() const {
|
||||
return m_sync.present;
|
||||
|
|
Loading…
Reference in New Issue