|
|
106311 |
qt-bugs@ issue : none
|
|
|
106311 |
bugs.kde.org number : none
|
|
|
106311 |
applied: no
|
|
|
106311 |
author: Lubos Lunak <l.lunak@kde.org>
|
|
|
106311 |
|
|
|
106311 |
Support for _NET_WM_SYNC_REQUEST - allows the WM to find out when the app
|
|
|
106311 |
finished one redraw - less flicker during resize and with compositing
|
|
|
106311 |
also when opening a window.
|
|
|
106311 |
|
|
|
106311 |
--- src/kernel/qwidget.h.sav 2007-06-22 14:14:05.000000000 +0200
|
|
|
106311 |
+++ src/kernel/qwidget.h 2007-06-23 11:53:39.000000000 +0200
|
|
|
106311 |
@@ -586,6 +586,14 @@ private:
|
|
|
106311 |
void destroyInputContext();
|
|
|
106311 |
void focusInputContext();
|
|
|
106311 |
void checkChildrenDnd();
|
|
|
106311 |
+
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+ void createSyncCounter();
|
|
|
106311 |
+ void destroySyncCounter();
|
|
|
106311 |
+ void incrementSyncCounter();
|
|
|
106311 |
+ void handleSyncRequest( void* ev );
|
|
|
106311 |
+#endif
|
|
|
106311 |
+
|
|
|
106311 |
#elif defined(Q_WS_MAC)
|
|
|
106311 |
uint own_id : 1, macDropEnabled : 1;
|
|
|
106311 |
EventHandlerRef window_event;
|
|
|
106311 |
@@ -962,8 +970,12 @@ struct Q_EXPORT QTLWExtra {
|
|
|
106311 |
uint uspos : 1; // User defined position
|
|
|
106311 |
uint ussize : 1; // User defined size
|
|
|
106311 |
#if defined(QT_NO_IM_EXTENSIONS)
|
|
|
106311 |
void *xic; // Input Context
|
|
|
106311 |
#endif
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+ ulong syncCounter;
|
|
|
106311 |
+ uint syncRequestValue[2];
|
|
|
106311 |
+#endif
|
|
|
106311 |
#endif
|
|
|
106311 |
#if defined(Q_WS_MAC)
|
|
|
106311 |
WindowGroupRef group;
|
|
|
106311 |
--- src/kernel/qt_x11_p.h.sav 2007-02-23 14:01:18.000000000 +0100
|
|
|
106311 |
+++ src/kernel/qt_x11_p.h 2007-06-23 11:53:39.000000000 +0200
|
|
|
106311 |
@@ -174,6 +174,11 @@ extern "C" {
|
|
|
106311 |
#endif // QT_NO_XRENDER
|
|
|
106311 |
|
|
|
106311 |
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+# include <X11/extensions/sync.h>
|
|
|
106311 |
+#endif // QT_NO_XSYNC
|
|
|
106311 |
+
|
|
|
106311 |
+
|
|
|
106311 |
#ifndef QT_NO_XKB
|
|
|
106311 |
# include <X11/XKBlib.h>
|
|
|
106311 |
#endif // QT_NO_XKB
|
|
|
106311 |
--- src/kernel/qwidget_x11.cpp.sav 2007-04-16 13:47:26.000000000 +0200
|
|
|
106311 |
+++ src/kernel/qwidget_x11.cpp 2007-06-23 19:48:44.000000000 +0200
|
|
|
106311 |
@@ -87,6 +87,12 @@ static QWidget *keyboardGrb = 0;
|
|
|
106311 |
extern Time qt_x_time;
|
|
|
106311 |
extern Time qt_x_user_time;
|
|
|
106311 |
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+extern Atom qt_net_wm_sync_request_counter;
|
|
|
106311 |
+extern Atom qt_net_wm_sync_request;
|
|
|
106311 |
+extern bool qt_use_xsync;
|
|
|
106311 |
+#endif
|
|
|
106311 |
+
|
|
|
106311 |
// defined in qfont_x11.cpp
|
|
|
106311 |
extern bool qt_has_xft;
|
|
|
106311 |
|
|
|
106311 |
@@ -595,11 +601,14 @@ void QWidget::create( WId window, bool i
|
|
|
106311 |
|
|
|
106311 |
XResizeWindow( dpy, id, crect.width(), crect.height() );
|
|
|
106311 |
XStoreName( dpy, id, qAppName() );
|
|
|
106311 |
- Atom protocols[4];
|
|
|
106311 |
+ Atom protocols[5];
|
|
|
106311 |
int n = 0;
|
|
|
106311 |
protocols[n++] = qt_wm_delete_window; // support del window protocol
|
|
|
106311 |
protocols[n++] = qt_wm_take_focus; // support take focus window protocol
|
|
|
106311 |
protocols[n++] = qt_net_wm_ping; // support _NET_WM_PING protocol
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+ protocols[n++] = qt_net_wm_sync_request;// support the _NET_WM_SYNC_REQUEST protocol
|
|
|
106311 |
+#endif
|
|
|
106311 |
if ( testWFlags( WStyle_ContextHelp ) )
|
|
|
106311 |
protocols[n++] = qt_net_wm_context_help;
|
|
|
106311 |
XSetWMProtocols( dpy, id, protocols, n );
|
|
|
106311 |
@@ -625,6 +634,14 @@ void QWidget::create( WId window, bool i
|
|
|
106311 |
XChangeProperty(dpy, id, qt_net_wm_pid, XA_CARDINAL, 32, PropModeReplace,
|
|
|
106311 |
(unsigned char *) &curr_pid, 1);
|
|
|
106311 |
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+ // set _NET_WM_SYNC_COUNTER
|
|
|
106311 |
+ createSyncCounter();
|
|
|
106311 |
+ long counterVal = topData()->syncCounter;
|
|
|
106311 |
+ XChangeProperty( dpy, id, qt_net_wm_sync_request_counter, XA_CARDINAL, 32, PropModeReplace,
|
|
|
106311 |
+ (unsigned char*) &counterVal, 1);
|
|
|
106311 |
+#endif
|
|
|
106311 |
+
|
|
|
106311 |
// when we create a toplevel widget, the frame strut should be dirty
|
|
|
106311 |
fstrut_dirty = 1;
|
|
|
106311 |
|
|
|
106311 |
@@ -720,6 +737,9 @@ void QWidget::destroy( bool destroyWindo
|
|
|
106311 |
if ( destroyWindow )
|
|
|
106311 |
qt_XDestroyWindow( this, x11Display(), winid );
|
|
|
106311 |
}
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+ destroySyncCounter();
|
|
|
106311 |
+#endif
|
|
|
106311 |
setWinId( 0 );
|
|
|
106311 |
|
|
|
106311 |
extern void qPRCleanup( QWidget *widget ); // from qapplication_x11.cpp
|
|
|
106311 |
@@ -769,6 +789,10 @@ void QWidget::reparentSys( QWidget *pare
|
|
|
106311 |
destroyInputContext();
|
|
|
106311 |
}
|
|
|
106311 |
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+ destroySyncCounter();
|
|
|
106311 |
+#endif
|
|
|
106311 |
+
|
|
|
106311 |
if ( isTopLevel() || !parent ) // we are toplevel, or reparenting to toplevel
|
|
|
106311 |
topData()->parentWinId = 0;
|
|
|
106311 |
|
|
|
106311 |
@@ -2456,8 +2480,13 @@ void QWidget::createTLSysExtra()
|
|
|
106311 |
{
|
|
|
106311 |
#if defined(QT_NO_IM_EXTENSIONS)
|
|
|
106311 |
// created lazily
|
|
|
106311 |
extra->topextra->xic = 0;
|
|
|
106311 |
#endif
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+ extra->topextra->syncCounter = 0;
|
|
|
106311 |
+ extra->topextra->syncRequestValue[0] = 0;
|
|
|
106311 |
+ extra->topextra->syncRequestValue[1] = 0;
|
|
|
106311 |
+#endif
|
|
|
106311 |
}
|
|
|
106311 |
|
|
|
106311 |
void QWidget::deleteTLSysExtra()
|
|
|
106311 |
@@ -2501,6 +2530,51 @@ void QWidget::checkChildrenDnd()
|
|
|
106311 |
}
|
|
|
106311 |
}
|
|
|
106311 |
|
|
|
106311 |
+
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+// create a window's XSyncCounter
|
|
|
106311 |
+void QWidget::createSyncCounter()
|
|
|
106311 |
+{
|
|
|
106311 |
+ if( !qt_use_xsync || !isTopLevel() || topData()->syncCounter )
|
|
|
106311 |
+ return;
|
|
|
106311 |
+ XSyncValue zero;
|
|
|
106311 |
+ XSyncIntToValue( &zero, 0 );
|
|
|
106311 |
+ topData()->syncCounter = XSyncCreateCounter( x11Display(), zero );
|
|
|
106311 |
+}
|
|
|
106311 |
+
|
|
|
106311 |
+// destroy a window's XSyncCounter
|
|
|
106311 |
+void QWidget::destroySyncCounter()
|
|
|
106311 |
+{
|
|
|
106311 |
+ if( !qt_use_xsync || !extra || !extra->topextra
|
|
|
106311 |
+ || !extra->topextra->syncCounter )
|
|
|
106311 |
+ return;
|
|
|
106311 |
+ XSyncDestroyCounter( x11Display(), extra->topextra->syncCounter );
|
|
|
106311 |
+ extra->topextra->syncCounter = 0;
|
|
|
106311 |
+}
|
|
|
106311 |
+
|
|
|
106311 |
+// increment a window's XSyncCounter
|
|
|
106311 |
+void QWidget::incrementSyncCounter()
|
|
|
106311 |
+{
|
|
|
106311 |
+ if( qt_use_xsync && topData()->syncCounter &&
|
|
|
106311 |
+ !(topData()->syncRequestValue[0] == 0 &&
|
|
|
106311 |
+ topData()->syncRequestValue[1] == 0) ) {
|
|
|
106311 |
+ XSyncValue val;
|
|
|
106311 |
+ XSyncIntsToValue( &val, topData()->syncRequestValue[ 0 ], topData()->syncRequestValue[ 1 ] );
|
|
|
106311 |
+ XSyncSetCounter( x11Display(), topData()->syncCounter, val );
|
|
|
106311 |
+ topData()->syncRequestValue[0] = topData()->syncRequestValue[1] = 0;
|
|
|
106311 |
+ }
|
|
|
106311 |
+}
|
|
|
106311 |
+
|
|
|
106311 |
+// handle _NET_WM_SYNC_REQUEST
|
|
|
106311 |
+void QWidget::handleSyncRequest( void* ev )
|
|
|
106311 |
+{
|
|
|
106311 |
+ XEvent* xev = (XEvent*)ev;
|
|
|
106311 |
+ topData()->syncRequestValue[ 0 ] = xev->xclient.data.l[ 2 ];
|
|
|
106311 |
+ topData()->syncRequestValue[ 1 ] = xev->xclient.data.l[ 3 ];
|
|
|
106311 |
+}
|
|
|
106311 |
+#endif // QT_NO_XSYNC
|
|
|
106311 |
+
|
|
|
106311 |
+
|
|
|
106311 |
/*!
|
|
|
106311 |
\property QWidget::acceptDrops
|
|
|
106311 |
\brief whether drop events are enabled for this widget
|
|
|
106311 |
--- src/kernel/qapplication_x11.cpp.sav 2007-04-16 13:47:26.000000000 +0200
|
|
|
106311 |
+++ src/kernel/qapplication_x11.cpp 2007-06-23 19:49:15.000000000 +0200
|
|
|
106311 |
@@ -285,6 +285,11 @@ Atom *qt_net_supported_list = 0;
|
|
|
106311 |
Window *qt_net_virtual_root_list = 0;
|
|
|
106311 |
|
|
|
106311 |
|
|
|
106311 |
+// X11 SYNC support
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+Atom qt_net_wm_sync_request_counter = 0;
|
|
|
106311 |
+Atom qt_net_wm_sync_request = 0;
|
|
|
106311 |
+#endif
|
|
|
106311 |
|
|
|
106311 |
// client leader window
|
|
|
106311 |
Window qt_x11_wm_client_leader = 0;
|
|
|
106311 |
@@ -309,6 +314,13 @@ static int xrandr_eventbase;
|
|
|
106311 |
// Display
|
|
|
106311 |
Q_EXPORT bool qt_use_xrender = FALSE;
|
|
|
106311 |
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+// True if SYNC extension exists on the connected display
|
|
|
106311 |
+bool qt_use_xsync = FALSE;
|
|
|
106311 |
+static int xsync_eventbase;
|
|
|
106311 |
+static int xsync_errorbase;
|
|
|
106311 |
+#endif
|
|
|
106311 |
+
|
|
|
106311 |
// modifier masks for alt/meta - detected when the application starts
|
|
|
106311 |
static long qt_alt_mask = 0;
|
|
|
106311 |
static long qt_meta_mask = 0;
|
|
|
106311 |
@@ -1938,6 +1950,11 @@ void qt_init_internal( int *argcptr, cha
|
|
|
106311 |
qt_x11_intern_atom( "UTF8_STRING", &qt_utf8_string );
|
|
|
106311 |
qt_x11_intern_atom( "_SGI_DESKS_MANAGER", &qt_sgi_desks_manager );
|
|
|
106311 |
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+ qt_x11_intern_atom( "_NET_WM_SYNC_REQUEST_COUNTER", &qt_net_wm_sync_request_counter );
|
|
|
106311 |
+ qt_x11_intern_atom( "_NET_WM_SYNC_REQUEST", &qt_net_wm_sync_request );
|
|
|
106311 |
+#endif
|
|
|
106311 |
+
|
|
|
106311 |
qt_xdnd_setup();
|
|
|
106311 |
qt_x11_motifdnd_init();
|
|
|
106311 |
|
|
|
106311 |
@@ -1974,6 +1991,15 @@ void qt_init_internal( int *argcptr, cha
|
|
|
106311 |
}
|
|
|
106311 |
#endif // QT_NO_XRENDER
|
|
|
106311 |
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+ // Try to initialize SYNC extension on the connected display
|
|
|
106311 |
+ int xsync_major, xsync_minor;
|
|
|
106311 |
+ if ( XSyncQueryExtension( appDpy, &xsync_eventbase, &xsync_errorbase ) &&
|
|
|
106311 |
+ XSyncInitialize( appDpy, &xsync_major, &xsync_minor ) ) {
|
|
|
106311 |
+ qt_use_xsync = TRUE;
|
|
|
106311 |
+ }
|
|
|
106311 |
+#endif
|
|
|
106311 |
+
|
|
|
106311 |
#ifndef QT_NO_XKB
|
|
|
106311 |
// If XKB is detected, set the GrabsUseXKBState option so input method
|
|
|
106311 |
// compositions continue to work (ie. deadkeys)
|
|
|
106311 |
@@ -3141,6 +3167,10 @@ int QApplication::x11ClientMessage(QWidg
|
|
|
106311 |
XSendEvent( event->xclient.display, event->xclient.window,
|
|
|
106311 |
False, SubstructureNotifyMask|SubstructureRedirectMask, event );
|
|
|
106311 |
}
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+ } else if (a == qt_net_wm_sync_request ) {
|
|
|
106311 |
+ widget->handleSyncRequest( event );
|
|
|
106311 |
+#endif
|
|
|
106311 |
}
|
|
|
106311 |
} else if ( event->xclient.message_type == qt_qt_scrolldone ) {
|
|
|
106311 |
widget->translateScrollDoneEvent(event);
|
|
|
106311 |
@@ -5681,6 +5711,21 @@ bool QETWidget::translateScrollDoneEvent
|
|
|
106311 |
return FALSE;
|
|
|
106311 |
}
|
|
|
106311 |
|
|
|
106311 |
+#if defined(Q_C_CALLBACKS)
|
|
|
106311 |
+extern "C" {
|
|
|
106311 |
+#endif
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+static Bool qt_net_wm_sync_request_scanner(Display*, XEvent* event, XPointer arg)
|
|
|
106311 |
+{
|
|
|
106311 |
+ return (event->type == ClientMessage && event->xclient.window == *(Window*)arg
|
|
|
106311 |
+ && event->xclient.message_type == qt_wm_protocols
|
|
|
106311 |
+ && event->xclient.data.l[ 0 ] == qt_net_wm_sync_request );
|
|
|
106311 |
+}
|
|
|
106311 |
+#endif
|
|
|
106311 |
+
|
|
|
106311 |
+#if defined(Q_C_CALLBACKS)
|
|
|
106311 |
+}
|
|
|
106311 |
+#endif
|
|
|
106311 |
|
|
|
106311 |
//
|
|
|
106311 |
// ConfigureNotify (window move and resize) event translation
|
|
|
106311 |
@@ -5712,6 +5757,7 @@ bool QETWidget::translateConfigEvent( co
|
|
|
106311 |
if (! extra || extra->compress_events) {
|
|
|
106311 |
// ConfigureNotify compression for faster opaque resizing
|
|
|
106311 |
XEvent otherEvent;
|
|
|
106311 |
+ int compressed_configs = 0;
|
|
|
106311 |
while ( XCheckTypedWindowEvent( x11Display(), winId(), ConfigureNotify,
|
|
|
106311 |
&otherEvent ) ) {
|
|
|
106311 |
if ( qt_x11EventFilter( &otherEvent ) )
|
|
|
106311 |
@@ -5732,7 +5778,18 @@ bool QETWidget::translateConfigEvent( co
|
|
|
106311 |
newCPos.ry() = otherEvent.xconfigure.y +
|
|
|
106311 |
otherEvent.xconfigure.border_width;
|
|
|
106311 |
}
|
|
|
106311 |
+ ++compressed_configs;
|
|
|
106311 |
+ }
|
|
|
106311 |
+#ifndef QT_NO_XSYNC
|
|
|
106311 |
+ // _NET_WM_SYNC_REQUEST compression
|
|
|
106311 |
+ Window wid = winId();
|
|
|
106311 |
+ while ( compressed_configs &&
|
|
|
106311 |
+ XCheckIfEvent( x11Display(), &otherEvent,
|
|
|
106311 |
+ qt_net_wm_sync_request_scanner, (XPointer)&wid ) ) {
|
|
|
106311 |
+ handleSyncRequest( (void*)&otherEvent );
|
|
|
106311 |
+ --compressed_configs;
|
|
|
106311 |
}
|
|
|
106311 |
+#endif
|
|
|
106311 |
}
|
|
|
106311 |
|
|
|
106311 |
QRect cr ( geometry() );
|
|
|
106311 |
@@ -5786,6 +5843,8 @@ bool QETWidget::translateConfigEvent( co
|
|
|
106311 |
repaint( !testWFlags(WResizeNoErase) || transbg );
|
|
|
106311 |
}
|
|
|
106311 |
|
|
|
106311 |
+ incrementSyncCounter();
|
|
|
106311 |
+
|
|
|
106311 |
return TRUE;
|
|
|
106311 |
}
|
|
|
106311 |
|