1
2 This let's IE fullscreen correctly in standards compliant WMs, though it also reveals a bug in our rebar control which can cause a (temporary?) deadlock when leaving fullscreen mode.
3
4 --- dlls/x11drv/window.c
5 +++ dlls/x11drv/window.c
6 @@ -74,6 +74,8 @@
7 "DndSelection",
8 "_MOTIF_WM_HINTS",
9 "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR",
10 + "_NET_WM_STATE",
11 + "_NET_WM_STATE_FULLSCREEN",
12 "_NET_WM_PID",
13 "_NET_WM_PING",
14 "_NET_WM_NAME",
15 @@ -114,6 +116,7 @@
16 inline static BOOL is_window_managed( WND *win )
17 {
18 if (!managed_mode) return FALSE;
19 +
20
21 if (win->dwExStyle & WS_EX_TRAYWINDOW) return TRUE;
22
23 @@ -126,13 +129,9 @@
24 if (win->dwStyle & WS_THICKFRAME) return TRUE;
25
26 if (win->dwExStyle & WS_EX_APPWINDOW) return TRUE;
27 -
28 - if ((win->dwStyle & WS_POPUP) &&
29 - (win->rectWindow.right-win->rectWindow.left) == screen_width &&
30 - (win->rectWindow.bottom-win->rectWindow.top) == screen_height)
31 - {
32 - return TRUE;
33 - }
34 +
35 + if (win->dwStyle & WS_SYSMENU) return TRUE;
36 +
37
38 return FALSE;
39 }
40 @@ -177,7 +176,6 @@
41 return (CWOverrideRedirect | CWSaveUnder | CWEventMask | CWColormap | CWCursor);
42 }
43
44 -
45
46
47
48
49
50
51
52
53
54
55
56 + if ( !(win->dwStyle & WS_THICKFRAME) && !data->fullscreened)
57 {
58 size_hints->max_width = data->whole_rect.right - data->whole_rect.left;
59 size_hints->max_height = data->whole_rect.bottom - data->whole_rect.top;
60 @@ -448,7 +449,7 @@
61 if (win->dwStyle & WS_MAXIMIZEBOX) mwm_hints.functions |= MWM_FUNC_MAXIMIZE;
62 if (win->dwStyle & WS_SYSMENU) mwm_hints.functions |= MWM_FUNC_CLOSE;
63 mwm_hints.decorations = 0;
64 - if ((win->dwStyle & WS_CAPTION) == WS_CAPTION) mwm_hints.decorations |= MWM_DECOR_TITLE;
65 + if (((win->dwStyle & WS_CAPTION) == WS_CAPTION) && !data->fullscreened) mwm_hints.decorations |= MWM_DECOR_TITLE;
66 if (win->dwExStyle & WS_EX_DLGMODALFRAME) mwm_hints.decorations |= MWM_DECOR_BORDER;
67 else if (win->dwStyle & WS_THICKFRAME) mwm_hints.decorations |= MWM_DECOR_BORDER | MWM_DECOR_RESIZEH;
68 else if ((win->dwStyle & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME) mwm_hints.decorations |= MWM_DECOR_BORDER;
69 @@ -465,6 +466,15 @@
70 XChangeProperty( display, data->whole_window, x11drv_atom(XdndAware),
71 XA_ATOM, 32, PropModeReplace, (unsigned char*)&dndVersion, 1 );
72
73 +
74 + if (data->fullscreened && !(win->dwStyle & WS_VISIBLE)) {
75 + Atom newstate = x11drv_atom(_NET_WM_STATE_FULLSCREEN);
76 +
77 + TRACE("setting state to _NET_WM_STATE_FULLSCREEN\n");
78 + XChangeProperty( display, data->whole_window, x11drv_atom(_NET_WM_STATE),
79 + XA_ATOM, 32, PropModeReplace, (unsigned char*)&newstate, 1 );
80 + }
81 +
82 wm_hints = XAllocWMHints();
83 wine_tsx11_unlock();
84
85 @@ -762,6 +772,8 @@
86 RECT rect;
87 BOOL is_top_level = is_window_top_level( win );
88
89 + data->fullscreened = FALSE;
90 +
91 rect = win->rectWindow;
92 X11DRV_window_to_X_rect( win, &rect );
93
94 --- dlls/x11drv/winpos.c
95 +++ dlls/x11drv/winpos.c
96 @@ -3,6 +3,7 @@
97 *
98 * Copyright 1993, 1994, 1995, 2001 Alexandre Julliard
99 * Copyright 1995, 1996, 1999 Alex Korobka
100 + * Copyright 2004 Mike Hearn for CodeWeavers
101 *
102 * This library is free software; you can redistribute it and/or
103 * modify it under the terms of the GNU Lesser General Public
104 @@ -74,6 +75,46 @@
105
106
107
108
109
110
111
112
113 +static void toggle_fullscreen( HWND hwnd )
114 +{
115 + WND *win = WIN_GetPtr(hwnd);
116 + struct x11drv_win_data *data = win->pDriverData;
117 + XEvent xev;
118 +
119 + TRACE("hwnd=%p, current=%s\n", hwnd, data->fullscreened ? "true" : "false");
120 + data->fullscreened = !data->fullscreened;
121 +
122 + wine_tsx11_lock();
123 +
124 + X11DRV_set_wm_hints(thread_display(), win);
125 +
126 + if (win->dwStyle & WS_VISIBLE) {
127 + TRACE("toggling fullscreen state\n");
128 + xev.xclient.type = ClientMessage;
129 + xev.xclient.window = data->whole_window;
130 + xev.xclient.message_type = x11drv_atom(_NET_WM_STATE);
131 + xev.xclient.serial = 0;
132 + xev.xclient.display = thread_display();
133 + xev.xclient.send_event = True;
134 + xev.xclient.format = 32;
135 +
136 + xev.xclient.data.l[0] = (data->fullscreened ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE);
137 + xev.xclient.data.l[1] = x11drv_atom(_NET_WM_STATE_FULLSCREEN);
138 + xev.xclient.data.l[2] = 0;
139 + XSendEvent(thread_display(), root_window, False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
140 + TRACE("toggled\n");
141 + }
142 +
143 + wine_tsx11_unlock();
144 + WIN_ReleasePtr(win);
145 +}
146 +
147 +
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189 +
190 + if (!fromXEvent
191 + && !(winpos->flags & (SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE))
192 + && !((newWindowRect.left < 0) && (newWindowRect.top < 0))) {
193 +
194 + TRACE("releasing fullscreen for %p\n", winpos->hwnd);
195 + toggle_fullscreen( winpos->hwnd );
196 + }
197 + }
198 +
199
200 if (!fixup_flags( winpos )) return FALSE;
201 -
202 - if (!(wndPtr = WIN_FindWndPtr( winpos->hwnd ))) return FALSE;
203 -
204 +
205 TRACE("\tcurrent (%ld,%ld)-(%ld,%ld), style %08x\n",
206 wndPtr->rectWindow.left, wndPtr->rectWindow.top,
207 wndPtr->rectWindow.right, wndPtr->rectWindow.bottom, (unsigned)wndPtr->dwStyle );
208 @@ -965,15 +1025,16 @@
209 }
210
211
212 + wvrFlags = SWP_DoNCCalcSize( winpos, &newWindowRect, &newClientRect );
213
214 - wvrFlags = SWP_DoNCCalcSize( winpos, &newWindowRect, &newClientRect );
215 -
216 + TRACE("after NC_CALCSIZE (%ld,%ld,%ld,%ld)\n", newWindowRect.left, newWindowRect.top, newWindowRect.right, newWindowRect.bottom);
217 +
218 if(!(winpos->flags & SWP_NOZORDER) && winpos->hwnd != winpos->hwndInsertAfter)
219 {
220 HWND parent = GetAncestor( winpos->hwnd, GA_PARENT );
221 if (parent) WIN_LinkWindow( winpos->hwnd, parent, winpos->hwndInsertAfter );
222 }
223 -
224 +
225
226
227 if( (((winpos->flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) &&
228 @@ -1039,6 +1100,7 @@
229 XClearArea( display, get_whole_window(wndPtr), 0, 0, 0, 0, True );
230 winpos->flags |= SWP_FRAMECHANGED;
231 }
232 +
233 if (winpos->flags & SWP_SHOWWINDOW)
234 {
235 set_visible_style( winpos->hwnd, TRUE );
236 @@ -1177,6 +1239,7 @@
237 POINT size;
238 LONG old_style;
239 WINDOWPLACEMENT wpl;
240 + struct x11drv_win_data* data;
241
242 TRACE("%p %u\n", hwnd, cmd );
243
244 @@ -1195,13 +1258,24 @@
245
246 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
247
248 + data = wndPtr->pDriverData;
249 +
250 size.x = wndPtr->rectWindow.left;
251 size.y = wndPtr->rectWindow.top;
252
253 +
254
255 + if ((wndPtr->dwStyle & WS_CAPTION) != WS_CAPTION) {
256 + if (((cmd == SW_RESTORE) && data->fullscreened) || ((cmd == SW_MAXIMIZE) && !data->fullscreened)) {
257 + TRACE("toggling fullscreen due to %s of captionless window %p\n", cmd == SW_MAXIMIZE ? "maximization" : "restoration", hwnd);
258 + toggle_fullscreen( hwnd );
259 + }
260 + }
261 +
262 switch( cmd )
263 {
264 case SW_MINIMIZE:
265 - if( wndPtr->dwStyle & WS_MAXIMIZE) wndPtr->flags |= WIN_RESTORE_MAX;
266 + if (wndPtr->dwStyle & WS_MAXIMIZE) wndPtr->flags |= WIN_RESTORE_MAX;
267 else wndPtr->flags &= ~WIN_RESTORE_MAX;
268
269 WIN_SetStyle( hwnd, (wndPtr->dwStyle & ~WS_MAXIMIZE) | WS_MINIMIZE );
270 @@ -1692,8 +1766,10 @@
271
272 if (winpos.flags == (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE)) return;
273
274 + TRACE("syncing window pos enter\n");
275 SetWindowPos( hwnd, winpos.hwndInsertAfter, winpos.x, winpos.y,
276 winpos.cx, winpos.cy, winpos.flags | SWP_WINE_NOHOSTMOVE );
277 + TRACE("syncing window pos leave\n");
278 }
279
280
281 --- dlls/x11drv/x11drv.h
282 +++ dlls/x11drv/x11drv.h
283 @@ -413,6 +413,8 @@
284 XATOM_DndSelection,
285 XATOM__MOTIF_WM_HINTS,
286 XATOM__KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR,
287 + XATOM__NET_WM_STATE,
288 + XATOM__NET_WM_STATE_FULLSCREEN,
289 XATOM__NET_WM_PID,
290 XATOM__NET_WM_PING,
291 XATOM__NET_WM_NAME,
292 @@ -446,6 +448,10 @@
293
294 #define x11drv_atom(name) (X11DRV_Atoms[XATOM_##name - FIRST_XATOM])
295
296 +#define _NET_WM_STATE_REMOVE 0
297 +#define _NET_WM_STATE_ADD 1
298 +#define _NET_WM_STATE_TOGGLE 2
299 +
300
301
302 typedef struct tagWINE_CLIPDATA {
303 @@ -511,6 +517,7 @@
304 XIC xic;
305 HBITMAP hWMIconBitmap;
306 HBITMAP hWMIconMask;
307 + BOOL fullscreened;
308 };
309
310 typedef struct x11drv_win_data X11DRV_WND_DATA;
311