Mercurial > pidgin.yaz
comparison gtk/plugins/win32/winprefs/gtkappbar.c @ 14224:ab8a105eff62
[gaim-migrate @ 16905]
First step of getting wingaim working again.
libgaim and gtk are compiling.
The protocols aren't compiling yet.
There are a number of things that are compiling, but should be cleaned up.
committer: Tailor Script <tailor@pidgin.im>
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Sun, 20 Aug 2006 16:49:37 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
14223:7c560c01b8f9 | 14224:ab8a105eff62 |
---|---|
1 /* | |
2 * gaim - WinGaim Options Plugin | |
3 * | |
4 * File: gtkappbar.c | |
5 * Date: August 2, 2003 | |
6 * Description: Appbar functionality for Windows GTK+ applications | |
7 * | |
8 * Copyright (C) 2003, Herman Bloggs <hermanator12002@yahoo.com> | |
9 * | |
10 * This program is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * This program is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this program; if not, write to the Free Software | |
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 * | |
24 */ | |
25 /* | |
26 * TODO: | |
27 * - Move 'App on top' feature from Trans plugin to here | |
28 * - Bug: Multiple Show/Hide Desktop calls causes client area to disappear | |
29 */ | |
30 #include <windows.h> | |
31 #include <winver.h> | |
32 #include <stdio.h> | |
33 #include <gtk/gtk.h> | |
34 #include <gdk/gdkwin32.h> | |
35 #include "gtkappbar.h" | |
36 #include "debug.h" | |
37 | |
38 #define APPBAR_CALLBACK WM_USER + 1010 | |
39 | |
40 typedef HMONITOR WINAPI gaim_MonitorFromPoint(POINT, DWORD); | |
41 typedef HMONITOR WINAPI gaim_MonitorFromWindow(HWND, DWORD); | |
42 typedef BOOL WINAPI gaim_GetMonitorInfo(HMONITOR, LPMONITORINFO); | |
43 | |
44 /* Retrieve the rectangular display area from the specified monitor | |
45 * Return TRUE if successful, otherwise FALSE | |
46 */ | |
47 static gboolean | |
48 get_rect_from_monitor(HMODULE hmod, HMONITOR monitor, RECT *rect) { | |
49 gaim_GetMonitorInfo *the_GetMonitorInfo; | |
50 MONITORINFO info; | |
51 | |
52 if (!(the_GetMonitorInfo = (gaim_GetMonitorInfo*) | |
53 GetProcAddress(hmod, "GetMonitorInfoA"))) { | |
54 return FALSE; | |
55 } | |
56 | |
57 info.cbSize = sizeof(info); | |
58 if (!the_GetMonitorInfo(monitor, &info)) { | |
59 return FALSE; | |
60 } | |
61 | |
62 CopyRect(rect, &(info.rcMonitor)); | |
63 | |
64 return TRUE; | |
65 } | |
66 | |
67 /** | |
68 * This will only work on Win98+ and Win2K+ | |
69 * Return TRUE if successful, otherwise FALSE | |
70 */ | |
71 static gboolean | |
72 get_rect_at_point_multimonitor(POINT pt, RECT *rect) { | |
73 HMODULE hmod; | |
74 gaim_MonitorFromPoint *the_MonitorFromPoint; | |
75 HMONITOR monitor; | |
76 | |
77 if (!(hmod = GetModuleHandle("user32"))) { | |
78 return FALSE; | |
79 } | |
80 | |
81 if (!(the_MonitorFromPoint = (gaim_MonitorFromPoint*) | |
82 GetProcAddress(hmod, "MonitorFromPoint"))) { | |
83 return FALSE; | |
84 } | |
85 | |
86 monitor = | |
87 the_MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY); | |
88 | |
89 return get_rect_from_monitor(hmod, monitor, rect); | |
90 } | |
91 | |
92 /** | |
93 * This will only work on Win98+ and Win2K+ | |
94 * Return TRUE if successful, otherwise FALSE | |
95 */ | |
96 static gboolean | |
97 get_rect_of_window_multimonitor(HWND window, RECT *rect) { | |
98 HMODULE hmod; | |
99 gaim_MonitorFromWindow *the_MonitorFromWindow; | |
100 HMONITOR monitor; | |
101 | |
102 if (!(hmod = GetModuleHandle("user32"))) { | |
103 return FALSE; | |
104 } | |
105 | |
106 if (!(the_MonitorFromWindow = (gaim_MonitorFromWindow*) | |
107 GetProcAddress(hmod, "MonitorFromWindow"))) { | |
108 return FALSE; | |
109 } | |
110 | |
111 monitor = | |
112 the_MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY); | |
113 | |
114 return get_rect_from_monitor(hmod, monitor, rect); | |
115 } | |
116 | |
117 /* | |
118 * Fallback if cannot get the RECT from the monitor directly | |
119 */ | |
120 static void get_default_workarea(RECT *rect) { | |
121 if (!SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, FALSE)) { | |
122 /* I don't think this will ever happen */ | |
123 rect->left = 0; | |
124 rect->top = 0; | |
125 rect->bottom = GetSystemMetrics(SM_CYSCREEN); | |
126 rect->right = GetSystemMetrics(SM_CXSCREEN); | |
127 } | |
128 } | |
129 | |
130 /* Retrieve the rectangle of the active work area at a point */ | |
131 static RECT get_rect_at_point(POINT pt) { | |
132 RECT rc; | |
133 if (!get_rect_at_point_multimonitor(pt, &rc)) { | |
134 get_default_workarea(&rc); | |
135 } | |
136 return rc; | |
137 } | |
138 | |
139 /* Retrieve the rectangle of the active work area of a window*/ | |
140 static RECT get_rect_of_window(HWND window) { | |
141 RECT rc; | |
142 if (!get_rect_of_window_multimonitor(window, &rc)) { | |
143 get_default_workarea(&rc); | |
144 } | |
145 return rc; | |
146 } | |
147 | |
148 static void get_window_normal_rc(HWND hwnd, RECT *rc) { | |
149 WINDOWPLACEMENT wplc; | |
150 GetWindowPlacement(hwnd, &wplc); | |
151 CopyRect(rc, &wplc.rcNormalPosition); | |
152 } | |
153 #if 0 | |
154 static void print_rect(RECT *rc) { | |
155 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "RECT: L:%ld R:%ld T:%ld B:%ld\n", | |
156 rc->left, rc->right, rc->top, rc->bottom); | |
157 } | |
158 #endif | |
159 /** Set the window style to be the "Tool Window" style - small header, no min/max buttons */ | |
160 static void set_toolbar(HWND hwnd, gboolean val) { | |
161 LONG style=0; | |
162 | |
163 style = GetWindowLong(hwnd, GWL_EXSTYLE); | |
164 if(val && !(style & WS_EX_TOOLWINDOW)) | |
165 style |= WS_EX_TOOLWINDOW; | |
166 else if(!val && style & WS_EX_TOOLWINDOW) | |
167 style &= ~WS_EX_TOOLWINDOW; | |
168 else | |
169 return; | |
170 SetWindowLong(hwnd, GWL_EXSTYLE, style); | |
171 SetWindowPos(hwnd, 0, 0, 0, 0, 0, | |
172 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); | |
173 | |
174 /* This really should be the following, but SWP_FRAMECHANGED strangely causes initermittent problems "Show Desktop" done more than once. | |
175 * Not having SWP_FRAMECHANGED *should* cause the Style not to be applied, but i haven't noticed any problems | |
176 * SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); | |
177 */ | |
178 } | |
179 /** Register the window as an appbar */ | |
180 static gboolean gtk_appbar_register(GtkAppBar *ab, HWND hwnd) { | |
181 APPBARDATA abd; | |
182 | |
183 abd.cbSize = sizeof(APPBARDATA); | |
184 abd.hWnd = hwnd; | |
185 abd.uCallbackMessage = APPBAR_CALLBACK; | |
186 | |
187 ab->registered = SHAppBarMessage(ABM_NEW, &abd); | |
188 | |
189 return ab->registered; | |
190 } | |
191 /** Unregister the window as an appbar */ | |
192 static gboolean gtk_appbar_unregister(GtkAppBar *ab, HWND hwnd) { | |
193 APPBARDATA abd; | |
194 | |
195 if(!ab->registered) | |
196 return TRUE; | |
197 | |
198 abd.cbSize = sizeof(APPBARDATA); | |
199 abd.hWnd = hwnd; | |
200 | |
201 SHAppBarMessage(ABM_REMOVE, &abd); /** This always returns TRUE */ | |
202 | |
203 ab->registered = FALSE; | |
204 | |
205 ab->docked = FALSE; | |
206 ab->docking = FALSE; | |
207 | |
208 return TRUE; | |
209 } | |
210 | |
211 static void gtk_appbar_querypos(GtkAppBar *ab, HWND hwnd, RECT rcWorkspace) { | |
212 APPBARDATA abd; | |
213 guint iWidth = 0; | |
214 | |
215 if(!ab->registered) | |
216 gtk_appbar_register(ab, hwnd); | |
217 | |
218 abd.hWnd = hwnd; | |
219 abd.cbSize = sizeof(APPBARDATA); | |
220 abd.uEdge = ab->side; | |
221 | |
222 iWidth = ab->docked_rect.right - ab->docked_rect.left; | |
223 | |
224 abd.rc.top = rcWorkspace.top; | |
225 abd.rc.bottom = rcWorkspace.bottom; | |
226 switch (abd.uEdge) | |
227 { | |
228 case ABE_LEFT: | |
229 abd.rc.left = rcWorkspace.left; | |
230 abd.rc.right = rcWorkspace.left + iWidth; | |
231 break; | |
232 | |
233 case ABE_RIGHT: | |
234 abd.rc.right = rcWorkspace.right; | |
235 abd.rc.left = rcWorkspace.right - iWidth; | |
236 break; | |
237 } | |
238 | |
239 /* Ask the system for the screen space */ | |
240 SHAppBarMessage(ABM_QUERYPOS, &abd); | |
241 | |
242 switch (abd.uEdge) | |
243 { | |
244 case ABE_LEFT: | |
245 abd.rc.right = abd.rc.left + iWidth; | |
246 break; | |
247 | |
248 case ABE_RIGHT: | |
249 abd.rc.left = abd.rc.right - iWidth; | |
250 break; | |
251 } | |
252 | |
253 CopyRect(&(ab->docked_rect), &abd.rc); | |
254 } | |
255 /* Actually set the size and screen location of the appbar */ | |
256 static void gtk_appbar_setpos(GtkAppBar *ab, HWND hwnd) { | |
257 APPBARDATA abd; | |
258 | |
259 if(!ab->registered) | |
260 gtk_appbar_register(ab, hwnd); | |
261 | |
262 abd.hWnd = hwnd; | |
263 abd.cbSize = sizeof(APPBARDATA); | |
264 CopyRect(&abd.rc, &(ab->docked_rect)); | |
265 abd.uEdge = ab->side; | |
266 | |
267 SHAppBarMessage(ABM_SETPOS, &abd); | |
268 } | |
269 /** Let any callbacks know that we have docked or undocked */ | |
270 static void gtk_appbar_dispatch_dock_cbs(GtkAppBar *ab, gboolean val) { | |
271 GList *lst = ab->dock_cbs; | |
272 | |
273 while(lst) { | |
274 GtkAppBarDockCB dock_cb = lst->data; | |
275 dock_cb(val); | |
276 lst = lst->next; | |
277 } | |
278 } | |
279 | |
280 static GdkFilterReturn wnd_moving(GtkAppBar *ab, GdkXEvent *xevent) { | |
281 MSG *msg = (MSG*)xevent; | |
282 POINT cp; | |
283 RECT *rc = (RECT*)msg->lParam; | |
284 RECT monRect; | |
285 int side = -1; | |
286 long dockAreaWidth = 0; | |
287 | |
288 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "wnd_moving\n"); | |
289 | |
290 GetCursorPos(&cp); | |
291 monRect = get_rect_at_point(cp); | |
292 | |
293 dockAreaWidth = (monRect.right - monRect.left) / 10; | |
294 /* Which part of the screen are we in ? */ | |
295 if (cp.x > (monRect.right - dockAreaWidth)) { | |
296 side = ABE_RIGHT; | |
297 } else if (cp.x < (monRect.left + dockAreaWidth)) { | |
298 side = ABE_LEFT; | |
299 } | |
300 | |
301 if(!ab->docked) { | |
302 if( (side == ABE_RIGHT || side == ABE_LEFT) ) { | |
303 if( !ab->docking ) { | |
304 ab->side = side; | |
305 GetWindowRect(msg->hwnd, &(ab->docked_rect)); | |
306 gtk_appbar_querypos(ab, msg->hwnd, monRect); | |
307 | |
308 /* save pre-docking height */ | |
309 ab->undocked_height = rc->bottom - rc->top; | |
310 ab->docking = TRUE; | |
311 } | |
312 } | |
313 else | |
314 ab->docking = FALSE; | |
315 } | |
316 else if(side < 0) { | |
317 gtk_appbar_unregister(ab, msg->hwnd); | |
318 rc->bottom = rc->top + ab->undocked_height; | |
319 } | |
320 | |
321 /* Switch to toolbar/regular caption*/ | |
322 if(ab->docking) | |
323 set_toolbar(msg->hwnd, TRUE); | |
324 else if(!ab->docked) | |
325 set_toolbar(msg->hwnd, FALSE); | |
326 | |
327 return GDK_FILTER_CONTINUE; | |
328 } | |
329 | |
330 static GdkFilterReturn wnd_sizing(GtkAppBar *ab, GdkXEvent *xevent) { | |
331 MSG *msg = (MSG*)xevent; | |
332 | |
333 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "wnd_sizing\n"); | |
334 if(ab->docked) { | |
335 RECT *rc = (RECT*)msg->lParam; | |
336 if(ab->side == ABE_LEFT && msg->wParam == WMSZ_RIGHT) { | |
337 ab->docked_rect.right = rc->right; | |
338 gtk_appbar_setpos(ab, msg->hwnd); | |
339 } | |
340 else if(ab->side == ABE_RIGHT && msg->wParam == WMSZ_LEFT) { | |
341 ab->docked_rect.left = rc->left; | |
342 gtk_appbar_setpos(ab, msg->hwnd); | |
343 } | |
344 return GDK_FILTER_REMOVE; | |
345 } | |
346 return GDK_FILTER_CONTINUE; | |
347 } | |
348 /** Notify the system that the appbar has been activated */ | |
349 static GdkFilterReturn wnd_activate(GtkAppBar *ab, GdkXEvent *xevent) { | |
350 if (ab->registered) { | |
351 APPBARDATA abd; | |
352 MSG *msg = (MSG*)xevent; | |
353 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "wnd_activate\n"); | |
354 | |
355 abd.hWnd = msg->hwnd; | |
356 abd.cbSize = sizeof(APPBARDATA); | |
357 | |
358 SHAppBarMessage(ABM_ACTIVATE, &abd); | |
359 } | |
360 return GDK_FILTER_CONTINUE; | |
361 } | |
362 /** Notify the system that the appbar's position has changed */ | |
363 static GdkFilterReturn wnd_poschanged(GtkAppBar *ab, GdkXEvent *xevent) { | |
364 if (ab->registered) { | |
365 APPBARDATA abd; | |
366 MSG *msg = (MSG*)xevent; | |
367 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "wnd_poschanged\n"); | |
368 | |
369 abd.hWnd = msg->hwnd; | |
370 abd.cbSize = sizeof(APPBARDATA); | |
371 | |
372 SHAppBarMessage(ABM_WINDOWPOSCHANGED, &abd); | |
373 } | |
374 return GDK_FILTER_CONTINUE; | |
375 } | |
376 /** The window is about to change */ | |
377 static GdkFilterReturn wnd_poschanging(GtkAppBar *ab, GdkXEvent *xevent) { | |
378 MSG *msg = (MSG*)xevent; | |
379 WINDOWPOS *wpos = (WINDOWPOS*)msg->lParam; | |
380 | |
381 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "wnd_poschanging\n"); | |
382 | |
383 if(ab->docked || ab->docking) { | |
384 wpos->x = ab->docked_rect.left; | |
385 wpos->y = ab->docked_rect.top; | |
386 wpos->cx = ab->docked_rect.right - ab->docked_rect.left; | |
387 wpos->cy = ab->docked_rect.bottom - ab->docked_rect.top; | |
388 if(IsIconic(msg->hwnd)) | |
389 set_toolbar(msg->hwnd, FALSE); | |
390 /*return GDK_FILTER_REMOVE;*/ | |
391 } | |
392 return GDK_FILTER_CONTINUE; | |
393 } | |
394 | |
395 static GdkFilterReturn wnd_exitsizemove(GtkAppBar *ab, GdkXEvent *xevent) { | |
396 MSG *msg = (MSG*)xevent; | |
397 | |
398 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "wnd_exitsizemove\n"); | |
399 if(ab->docking) { | |
400 gtk_appbar_setpos(ab, msg->hwnd); | |
401 ab->docking = FALSE; | |
402 ab->docked = TRUE; | |
403 gtk_appbar_dispatch_dock_cbs(ab, TRUE); | |
404 } | |
405 else if(!ab->docked) { | |
406 gtk_appbar_unregister(ab, msg->hwnd); | |
407 gtk_appbar_dispatch_dock_cbs(ab, FALSE); | |
408 } | |
409 | |
410 return GDK_FILTER_CONTINUE; | |
411 } | |
412 | |
413 static GdkFilterReturn wnd_showwindow(GtkAppBar *ab, GdkXEvent *xevent) { | |
414 MSG *msg = (MSG*)xevent; | |
415 | |
416 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "wnd_showwindow\n"); | |
417 if(msg->wParam && ab->docked) { | |
418 ab->iconized = FALSE; | |
419 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "shown\n"); | |
420 ab->docked = FALSE; | |
421 gtk_appbar_dock(ab, ab->side); | |
422 } | |
423 else if(!msg->wParam && ab->docked) { | |
424 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "hidden\n"); | |
425 gtk_appbar_unregister(ab, GDK_WINDOW_HWND(ab->win->window)); | |
426 set_toolbar(GDK_WINDOW_HWND(ab->win->window), FALSE); | |
427 ab->docked = TRUE; | |
428 ab->iconized = TRUE; | |
429 } | |
430 return GDK_FILTER_CONTINUE; | |
431 } | |
432 /** The window's size has changed */ | |
433 static GdkFilterReturn wnd_size(GtkAppBar *ab, GdkXEvent *xevent) { | |
434 MSG *msg = (MSG*)xevent; | |
435 | |
436 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "wnd_size\n"); | |
437 | |
438 if(msg->wParam == SIZE_MINIMIZED) { | |
439 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "Minimize\n"); | |
440 if(ab->docked) { | |
441 gtk_appbar_unregister(ab, GDK_WINDOW_HWND(ab->win->window)); | |
442 ab->docked = TRUE; | |
443 } | |
444 } | |
445 else if(msg->wParam == SIZE_RESTORED) { | |
446 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "Restore\n"); | |
447 if (!ab->iconized && ab->docked) { | |
448 gtk_appbar_dock(ab, ab->side); | |
449 } | |
450 } | |
451 return GDK_FILTER_CONTINUE; | |
452 } | |
453 | |
454 static GdkFilterReturn wnd_nchittest(GtkAppBar *ab, GdkXEvent *xevent) { | |
455 MSG *msg = (MSG*)xevent; | |
456 | |
457 if(ab->docked) { | |
458 UINT ret = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam); | |
459 | |
460 switch(ret) { | |
461 case HTBOTTOM: | |
462 case HTBOTTOMLEFT: | |
463 case HTBOTTOMRIGHT: | |
464 case HTTOP: | |
465 case HTTOPLEFT: | |
466 case HTTOPRIGHT: | |
467 return GDK_FILTER_REMOVE; | |
468 case HTLEFT: | |
469 if(ab->side == ABE_LEFT) | |
470 return GDK_FILTER_REMOVE; | |
471 break; | |
472 case HTRIGHT: | |
473 if(ab->side == ABE_RIGHT) | |
474 return GDK_FILTER_REMOVE; | |
475 break; | |
476 } | |
477 } | |
478 return GDK_FILTER_CONTINUE; | |
479 } | |
480 | |
481 #if 0 | |
482 static GdkFilterReturn wnd_initmenupopup(GtkAppBar *ab, GdkXEvent *xevent) { | |
483 MSG *msg = (MSG*)xevent; | |
484 | |
485 if(ab->docked && HIWORD(msg->lParam)) { | |
486 HMENU sysmenu = GetSystemMenu(msg->hwnd, FALSE); | |
487 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "wnd_initpopupmenu: docked: %d ismenu: %d\n", ab->docked, IsMenu(sysmenu)); | |
488 if(EnableMenuItem(sysmenu, SC_MAXIMIZE, MF_BYCOMMAND|MF_GRAYED)<0) | |
489 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "SC_MAXIMIZE Menu item does not exist\n"); | |
490 if(EnableMenuItem(sysmenu, SC_MOVE, MF_BYCOMMAND|MF_GRAYED)<0) | |
491 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "SC_MOVE Menu item does not exist\n"); | |
492 return GDK_FILTER_CONTINUE; | |
493 } | |
494 else | |
495 GetSystemMenu(msg->hwnd, TRUE); | |
496 return GDK_FILTER_CONTINUE; | |
497 } | |
498 #endif | |
499 | |
500 static GdkFilterReturn gtk_appbar_callback(GtkAppBar *ab, GdkXEvent *xevent) { | |
501 MSG *msg = (MSG*)xevent; | |
502 RECT orig; | |
503 | |
504 switch (msg->wParam) { | |
505 case ABN_STATECHANGE: | |
506 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_callback: ABN_STATECHANGE\n"); | |
507 break; | |
508 | |
509 case ABN_FULLSCREENAPP: | |
510 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_callback: ABN_FULLSCREENAPP: %d\n", (BOOL)msg->lParam); | |
511 if (!ab->iconized && ab->docked) { | |
512 if ((BOOL)msg->lParam) { | |
513 SetWindowPos(msg->hwnd, HWND_BOTTOM, 0, 0, 0, 0, | |
514 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); | |
515 } else { | |
516 SetWindowPos(msg->hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, | |
517 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED); | |
518 } | |
519 } | |
520 | |
521 break; | |
522 | |
523 case ABN_POSCHANGED: | |
524 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_callback: ABN_POSCHANGED\n"); | |
525 CopyRect(&orig, &(ab->docked_rect)); | |
526 gtk_appbar_querypos(ab, msg->hwnd, get_rect_of_window(msg->hwnd)); | |
527 if (EqualRect(&orig, &(ab->docked_rect)) == 0) { | |
528 MoveWindow(msg->hwnd, ab->docked_rect.left, ab->docked_rect.top, | |
529 ab->docked_rect.right - ab->docked_rect.left, | |
530 ab->docked_rect.bottom - ab->docked_rect.top, TRUE); | |
531 } | |
532 gtk_appbar_setpos(ab, msg->hwnd); | |
533 break; | |
534 #if 0 | |
535 default: | |
536 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_callback: %d\n", msg->wParam); | |
537 #endif | |
538 } | |
539 return GDK_FILTER_CONTINUE; | |
540 } | |
541 | |
542 static GdkFilterReturn gtk_appbar_event_filter(GdkXEvent *xevent, GdkEvent *event, gpointer data) { | |
543 MSG *msg = (MSG*)xevent; | |
544 | |
545 /*printf("MSG: %s\n", message_to_string (msg->message));*/ | |
546 switch(msg->message) { | |
547 case WM_EXITSIZEMOVE: | |
548 return wnd_exitsizemove(data, xevent); | |
549 case WM_WINDOWPOSCHANGING: | |
550 return wnd_poschanging(data, xevent); | |
551 case WM_WINDOWPOSCHANGED: | |
552 return wnd_poschanged(data, xevent); | |
553 case WM_ACTIVATE: | |
554 return wnd_activate(data, xevent); | |
555 case WM_SIZING: | |
556 return wnd_sizing(data, xevent); | |
557 case WM_MOVING: | |
558 return wnd_moving(data, xevent); | |
559 case WM_SHOWWINDOW: | |
560 return wnd_showwindow(data, xevent); | |
561 case WM_NCHITTEST: | |
562 return wnd_nchittest(data, xevent); | |
563 #if 0 | |
564 case WM_INITMENUPOPUP: | |
565 return wnd_initmenupopup(data, xevent); | |
566 #endif | |
567 case WM_SIZE: | |
568 return wnd_size(data, xevent); | |
569 case APPBAR_CALLBACK: | |
570 return gtk_appbar_callback(data, xevent); | |
571 #if 0 | |
572 default: | |
573 gaim_debug_info("gtkappbar", "gtk_appbar_event_filter %d\n", msg->message); | |
574 #endif | |
575 } | |
576 return GDK_FILTER_CONTINUE; | |
577 } | |
578 | |
579 void gtk_appbar_dock(GtkAppBar *ab, UINT side) { | |
580 RECT orig; | |
581 | |
582 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_dock\n"); | |
583 | |
584 if(!ab || !IsWindow(GDK_WINDOW_HWND(ab->win->window))) | |
585 return; | |
586 | |
587 ab->side = side; | |
588 get_window_normal_rc(GDK_WINDOW_HWND(ab->win->window), &(ab->docked_rect)); | |
589 CopyRect(&orig, &(ab->docked_rect)); | |
590 gtk_appbar_querypos(ab, GDK_WINDOW_HWND(ab->win->window), | |
591 get_rect_of_window(GDK_WINDOW_HWND(ab->win->window))); | |
592 if(EqualRect(&orig, &(ab->docked_rect)) == 0) | |
593 MoveWindow(GDK_WINDOW_HWND(ab->win->window), | |
594 ab->docked_rect.left, | |
595 ab->docked_rect.top, | |
596 ab->docked_rect.right - ab->docked_rect.left, | |
597 ab->docked_rect.bottom - ab->docked_rect.top, TRUE); | |
598 gtk_appbar_setpos(ab, GDK_WINDOW_HWND(ab->win->window)); | |
599 set_toolbar(GDK_WINDOW_HWND(ab->win->window), TRUE); | |
600 ab->docked = TRUE; | |
601 } | |
602 | |
603 void gtk_appbar_add_dock_cb(GtkAppBar *ab, GtkAppBarDockCB dock_cb) { | |
604 if(!ab) | |
605 return; | |
606 ab->dock_cbs = g_list_append(ab->dock_cbs, dock_cb); | |
607 } | |
608 | |
609 GtkAppBar *gtk_appbar_add(GtkWidget *win) { | |
610 GtkAppBar *ab; | |
611 | |
612 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_add\n"); | |
613 | |
614 if(!win) | |
615 return NULL; | |
616 ab = g_new0(GtkAppBar, 1); | |
617 ab->win = win; | |
618 | |
619 /* init docking coords */ | |
620 get_window_normal_rc(GDK_WINDOW_HWND(win->window), &(ab->docked_rect)); | |
621 | |
622 /* Add main window filter */ | |
623 gdk_window_add_filter(win->window, | |
624 gtk_appbar_event_filter, | |
625 ab); | |
626 return ab; | |
627 } | |
628 | |
629 void gtk_appbar_remove(GtkAppBar *ab) { | |
630 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_remove\n"); | |
631 | |
632 if(!ab) | |
633 return; | |
634 gdk_window_remove_filter(ab->win->window, | |
635 gtk_appbar_event_filter, | |
636 ab); | |
637 if(ab->docked) { | |
638 gtk_window_resize(GTK_WINDOW(ab->win), | |
639 ab->docked_rect.right - ab->docked_rect.left, | |
640 ab->undocked_height); | |
641 set_toolbar(GDK_WINDOW_HWND(ab->win->window), FALSE); | |
642 } | |
643 gtk_appbar_unregister(ab, GDK_WINDOW_HWND(ab->win->window)); | |
644 | |
645 g_free(ab); | |
646 } |