summaryrefslogtreecommitdiff
blob: 36ae67a6b7372b6318e90a05111805d9ffb8ba73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
Index: src/kernel/qapplication.h
===================================================================
--- src/kernel/qapplication.h	(revision 106)
+++ src/kernel/qapplication.h	(working copy)
@@ -411,6 +414,7 @@
 
     static bool      sendSpontaneousEvent( QObject *receiver, QEvent *event );
     static void      removePostedEvent( QEvent * );
+    static void      removePostedEvents( QObject *receiver, int event_type );
 
     friend class QWidget;
     friend class QETWidget;
Index: src/kernel/qapplication_x11.cpp
===================================================================
--- src/kernel/qapplication_x11.cpp	(revision 108)
+++ src/kernel/qapplication_x11.cpp	(working copy)
@@ -601,7 +601,21 @@
 */
 void QApplication::postIMEvent( QObject *receiver, QIMEvent *event )
 {
-    postEvent( receiver, event );
+    if ( event->type() == QEvent::IMCompose ) {
+	// enable event compression to reduce preedit flicker on fast
+	// typing
+	postEvent( receiver, event );
+    } else {
+	// cancel queued preedit update
+	if ( event->type() == QEvent::IMEnd )
+	    removePostedEvents( receiver, QEvent::IMCompose );
+
+	// to avoid event receiving order inversion between QKeyEvent
+	// and QIMEvent, we must send IMStart and IMEnd via
+	// sendEvent().
+	sendEvent( receiver, event );
+	delete event;
+    }
 }
 
 
Index: src/kernel/qapplication.cpp
===================================================================
--- src/kernel/qapplication.cpp	(revision 106)
+++ src/kernel/qapplication.cpp	(working copy)
@@ -3112,8 +3112,7 @@
 	 event->type() == QEvent::LayoutHint ||
 	 event->type() == QEvent::Resize ||
 	 event->type() == QEvent::Move ||
-	 event->type() == QEvent::LanguageChange ||
-	 event->type() == QEvent::IMCompose ) {
+	 event->type() == QEvent::LanguageChange ) {
 	l->first();
 	QPostEvent * cur = 0;
 	for ( ;; ) {
@@ -3147,6 +3146,29 @@
 		} else if ( cur->event->type() == QEvent::LanguageChange ) {
 		    delete event;
 		    return;
+		}
+	    }
+	    break;
+	};
+    }
+
+#if !defined(QT_NO_IM)
+    // if this is one of the compressible IM events, do compression
+    else if ( event->type() == QEvent::IMCompose ) {
+	l->last();
+	QPostEvent * cur = 0;
+	for ( ;; ) {
+	    while ( (cur=l->current()) != 0 &&
+		    ( cur->receiver != receiver ||
+		      cur->event == 0 ||
+		      cur->event->type() != event->type() || 
+		      cur->event->type() != QEvent::IMStart ) )
+		l->prev();
+	    if ( l->current() != 0 ) {
+		// IMCompose must not be compressed with another one
+		// beyond its IMStart boundary
+		if ( cur->event->type() == QEvent::IMStart ) {
+		    break;
 		} else if ( cur->event->type() == QEvent::IMCompose ) {
 		    QIMComposeEvent * e = (QIMComposeEvent *)(cur->event);
 		    *e = *(QIMComposeEvent *)event;
@@ -3157,6 +3179,7 @@
 	    break;
 	};
     }
+#endif
 
     // if no compression could be done, just append something
     event->posted = TRUE;
@@ -3304,6 +3327,23 @@
 
 void QApplication::removePostedEvents( QObject *receiver )
 {
+    removePostedEvents( receiver, 0 );
+}
+
+/*!
+  Removes all events that have the event type \a event_type posted
+  using postEvent() for \a receiver.
+
+  The events are \e not dispatched, instead they are removed from the
+  queue.
+
+  If \a event_type is 0, all the events are removed from the queue.
+
+  \threadsafe
+*/
+
+void QApplication::removePostedEvents( QObject *receiver, int event_type )
+{
     if ( !receiver )
 	return;
 
@@ -3322,18 +3362,22 @@
     // leave the QPostEvent objects; they'll be deleted by
     // sendPostedEvents().
     QPostEventList * l = receiver->postedEvents;
-    receiver->postedEvents = 0;
+    if ( !event_type )
+	receiver->postedEvents = 0;
     l->first();
     QPostEvent * pe;
     while( (pe=l->current()) != 0 ) {
-	if ( pe->event ) {
-	    pe->event->posted = FALSE;
-	    delete pe->event;
-	    pe->event = 0;
+	if ( !event_type || pe->event->type() == event_type ) {
+	    if ( pe->event ) {
+		pe->event->posted = FALSE;
+		delete pe->event;
+		pe->event = 0;
+	    }
+	    l->remove();
 	}
-	l->remove();
     }
-    delete l;
+    if ( !event_type )
+	delete l;
 }