|
@@ -9,6 +9,7 @@ is::XEngine::XEngine() {
|
9
|
9
|
m_good = false;
|
10
|
10
|
m_mousex = -1;
|
11
|
11
|
m_mousey = -1;
|
|
12
|
+ m_hoverXWindow = None;
|
12
|
13
|
}
|
13
|
14
|
|
14
|
15
|
is::XEngine::~XEngine() {
|
|
@@ -76,6 +77,16 @@ int is::XEngine::grabCursor( is::CursorType type ) {
|
76
|
77
|
printf( "Failed to grab X cursor\n" );
|
77
|
78
|
return 1;
|
78
|
79
|
}
|
|
80
|
+
|
|
81
|
+ // Quickly set the mouse position so we don't have to worry about x11 generating an event.
|
|
82
|
+ Window root, child;
|
|
83
|
+ int mx, my;
|
|
84
|
+ int wx, wy;
|
|
85
|
+ unsigned int mask;
|
|
86
|
+ XQueryPointer( m_display, m_root, &root, &child, &mx, &my, &wx, &wy, &mask );
|
|
87
|
+ m_mousex = mx;
|
|
88
|
+ m_mousex = my;
|
|
89
|
+ updateHoverWindow( child );
|
79
|
90
|
return 0;
|
80
|
91
|
}
|
81
|
92
|
|
|
@@ -91,7 +102,7 @@ void is::XEngine::tick() {
|
91
|
102
|
if ( !m_good ) {
|
92
|
103
|
return;
|
93
|
104
|
}
|
94
|
|
- XFlush( m_display );
|
|
105
|
+ XSync( m_display, false );
|
95
|
106
|
XEvent event;
|
96
|
107
|
while ( XPending( m_display ) ) {
|
97
|
108
|
XNextEvent( m_display, &event );
|
|
@@ -119,8 +130,12 @@ void is::XEngine::tick() {
|
119
|
130
|
}
|
120
|
131
|
break;
|
121
|
132
|
}
|
|
133
|
+ default: break;
|
122
|
134
|
}
|
123
|
135
|
}
|
|
136
|
+
|
|
137
|
+ // Since I couldn't get Xlib to send a EnterNotify or LeaveNotify events, we need to query the underlying window every frame.
|
|
138
|
+ updateHoverWindow();
|
124
|
139
|
}
|
125
|
140
|
|
126
|
141
|
Cursor is::XEngine::getCursor( is::CursorType type ) {
|
|
@@ -153,7 +168,7 @@ void is::XEngine::setCursor( is::CursorType type ) {
|
153
|
168
|
}
|
154
|
169
|
Cursor xfontcursor = getCursor( type );
|
155
|
170
|
XChangeActivePointerGrab( m_display,
|
156
|
|
- ButtonMotionMask | ButtonPressMask | ButtonReleaseMask,
|
|
171
|
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
|
157
|
172
|
xfontcursor, CurrentTime );
|
158
|
173
|
}
|
159
|
174
|
|
|
@@ -181,12 +196,6 @@ is::Rectangle::Rectangle( int x, int y, int width, int height, int border, int p
|
181
|
196
|
m_yoffset += m_height;
|
182
|
197
|
m_height = -m_height;
|
183
|
198
|
}
|
184
|
|
- if ( m_width == 0 ) {
|
185
|
|
- m_width = 1;
|
186
|
|
- }
|
187
|
|
- if ( m_height == 0 ) {
|
188
|
|
- m_height = 1;
|
189
|
|
- }
|
190
|
199
|
|
191
|
200
|
XAllocNamedColor( xengine->m_display, xengine->m_colormap, "black", &m_forground, &m_forgroundExact );
|
192
|
201
|
XAllocNamedColor( xengine->m_display, xengine->m_colormap, "white", &m_background, &m_backgroundExact );
|
|
@@ -200,7 +209,7 @@ is::Rectangle::Rectangle( int x, int y, int width, int height, int border, int p
|
200
|
209
|
CWSaveUnder | CWOverrideRedirect |
|
201
|
210
|
CWColormap;
|
202
|
211
|
|
203
|
|
- m_window = XCreateWindow( xengine->m_display, xengine->m_root, m_x+m_xoffset, m_y+m_yoffset, m_width+m_border*2, m_height+m_border*2,
|
|
212
|
+ m_window = XCreateWindow( xengine->m_display, xengine->m_root, m_x-m_border+m_xoffset, m_y-m_border+m_yoffset, m_width+m_border*2, m_height+m_border*2,
|
204
|
213
|
0, CopyFromParent, InputOutput,
|
205
|
214
|
CopyFromParent, valueMask, &attributes );
|
206
|
215
|
XRectangle rect;
|
|
@@ -240,12 +249,6 @@ void is::Rectangle::setDim( int w, int h ) {
|
240
|
249
|
m_yoffset += h;
|
241
|
250
|
m_height = -h;
|
242
|
251
|
}
|
243
|
|
- if ( m_width == 0 ) {
|
244
|
|
- m_width = 1;
|
245
|
|
- }
|
246
|
|
- if ( m_height == 0 ) {
|
247
|
|
- m_height = 1;
|
248
|
|
- }
|
249
|
252
|
XResizeWindow( xengine->m_display, m_window, m_width+m_border*2, m_height+m_border*2 );
|
250
|
253
|
XMoveWindow( xengine->m_display, m_window, m_x-m_border+m_xoffset, m_y-m_border+m_yoffset );
|
251
|
254
|
// Now punch another hole in it.
|
|
@@ -264,3 +267,49 @@ void is::Rectangle::setDim( int w, int h ) {
|
264
|
267
|
|
265
|
268
|
void is::Rectangle::draw() {
|
266
|
269
|
}
|
|
270
|
+
|
|
271
|
+void is::XEngine::updateHoverWindow() {
|
|
272
|
+ Window root, child;
|
|
273
|
+ int mx, my;
|
|
274
|
+ int wx, wy;
|
|
275
|
+ unsigned int mask;
|
|
276
|
+ XQueryPointer( m_display, m_root, &root, &child, &mx, &my, &wx, &wy, &mask );
|
|
277
|
+ if ( m_hoverXWindow == child ) {
|
|
278
|
+ return;
|
|
279
|
+ }
|
|
280
|
+ for ( unsigned int i=0; i<m_rects.size(); i++ ) {
|
|
281
|
+ if ( m_rects.at( i )->m_window == child ) {
|
|
282
|
+ return;
|
|
283
|
+ }
|
|
284
|
+ }
|
|
285
|
+ m_hoverXWindow = child;
|
|
286
|
+ if ( child == None ) {
|
|
287
|
+ return;
|
|
288
|
+ }
|
|
289
|
+ unsigned int depth;
|
|
290
|
+ XGetGeometry( m_display, child, &root,
|
|
291
|
+ &(m_hoverWindow.m_x), &(m_hoverWindow.m_y),
|
|
292
|
+ &(m_hoverWindow.m_width), &(m_hoverWindow.m_height),
|
|
293
|
+ &(m_hoverWindow.m_border), &depth );
|
|
294
|
+}
|
|
295
|
+
|
|
296
|
+void is::XEngine::updateHoverWindow( Window child ) {
|
|
297
|
+ if ( m_hoverXWindow == child ) {
|
|
298
|
+ return;
|
|
299
|
+ }
|
|
300
|
+ for ( unsigned int i=0; i<m_rects.size(); i++ ) {
|
|
301
|
+ if ( m_rects.at( i )->m_window == child ) {
|
|
302
|
+ return;
|
|
303
|
+ }
|
|
304
|
+ }
|
|
305
|
+ m_hoverXWindow = child;
|
|
306
|
+ if ( child == None ) {
|
|
307
|
+ return;
|
|
308
|
+ }
|
|
309
|
+ unsigned int depth;
|
|
310
|
+ Window root;
|
|
311
|
+ XGetGeometry( m_display, child, &root,
|
|
312
|
+ &(m_hoverWindow.m_x), &(m_hoverWindow.m_y),
|
|
313
|
+ &(m_hoverWindow.m_width), &(m_hoverWindow.m_height),
|
|
314
|
+ &(m_hoverWindow.m_border), &depth );
|
|
315
|
+}
|