| 2 * gaim - WinGaim Options Plugin |
2 * gaim - WinGaim Options Plugin |
| 3 * |
3 * |
| 4 * File: gtkappbar.c |
4 * File: gtkappbar.c |
| 5 * Date: August 2, 2003 |
5 * Date: August 2, 2003 |
| 6 * Description: Appbar functionality for Windows GTK+ applications |
6 * Description: Appbar functionality for Windows GTK+ applications |
| 7 * |
7 * |
| 8 * Copyright (C) 2003, Herman Bloggs <hermanator12002@yahoo.com> |
8 * Copyright (C) 2003, Herman Bloggs <hermanator12002@yahoo.com> |
| 9 * |
9 * |
| 10 * This program is free software; you can redistribute it and/or modify |
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 |
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 |
12 * the Free Software Foundation; either version 2 of the License, or |
| 126 rect->right = GetSystemMetrics(SM_CXSCREEN); |
126 rect->right = GetSystemMetrics(SM_CXSCREEN); |
| 127 } |
127 } |
| 128 } |
128 } |
| 129 |
129 |
| 130 /* Retrieve the rectangle of the active work area at a point */ |
130 /* Retrieve the rectangle of the active work area at a point */ |
| 131 static RECT get_rect_at_point(POINT pt) { |
131 static void get_rect_at_point(POINT pt, RECT *rc) { |
| 132 RECT rc; |
132 if (!get_rect_at_point_multimonitor(pt, rc)) { |
| 133 if (!get_rect_at_point_multimonitor(pt, &rc)) { |
133 get_default_workarea(rc); |
| 134 get_default_workarea(&rc); |
134 } |
| 135 } |
|
| 136 return rc; |
|
| 137 } |
135 } |
| 138 |
136 |
| 139 /* Retrieve the rectangle of the active work area of a window*/ |
137 /* Retrieve the rectangle of the active work area of a window*/ |
| 140 static RECT get_rect_of_window(HWND window) { |
138 static void get_rect_of_window(HWND window, RECT *rc) { |
| 141 RECT rc; |
139 if (!get_rect_of_window_multimonitor(window, rc)) { |
| 142 if (!get_rect_of_window_multimonitor(window, &rc)) { |
140 get_default_workarea(rc); |
| 143 get_default_workarea(&rc); |
141 } |
| 144 } |
|
| 145 return rc; |
|
| 146 } |
142 } |
| 147 |
143 |
| 148 static void get_window_normal_rc(HWND hwnd, RECT *rc) { |
144 static void get_window_normal_rc(HWND hwnd, RECT *rc) { |
| 149 WINDOWPLACEMENT wplc; |
145 WINDOWPLACEMENT wplc; |
| 150 GetWindowPlacement(hwnd, &wplc); |
146 GetWindowPlacement(hwnd, &wplc); |
| 171 SetWindowPos(hwnd, 0, 0, 0, 0, 0, |
167 SetWindowPos(hwnd, 0, 0, 0, 0, 0, |
| 172 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); |
168 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); |
| 173 |
169 |
| 174 /* This really should be the following, but SWP_FRAMECHANGED strangely causes initermittent problems "Show Desktop" done more than once. |
170 /* 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 |
171 * 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); |
172 * SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); |
| 177 */ |
173 */ |
| 178 } |
174 } |
| 179 /** Register the window as an appbar */ |
175 /** Register the window as an appbar */ |
| 180 static gboolean gtk_appbar_register(GtkAppBar *ab, HWND hwnd) { |
176 static gboolean gtk_appbar_register(GtkAppBar *ab, HWND hwnd) { |
| 181 APPBARDATA abd; |
177 APPBARDATA abd; |
| 210 |
206 |
| 211 static void gtk_appbar_querypos(GtkAppBar *ab, HWND hwnd, RECT rcWorkspace) { |
207 static void gtk_appbar_querypos(GtkAppBar *ab, HWND hwnd, RECT rcWorkspace) { |
| 212 APPBARDATA abd; |
208 APPBARDATA abd; |
| 213 guint iWidth = 0; |
209 guint iWidth = 0; |
| 214 |
210 |
| 215 if(!ab->registered) |
211 if(!ab->registered) |
| 216 gtk_appbar_register(ab, hwnd); |
212 gtk_appbar_register(ab, hwnd); |
| 217 |
213 |
| 218 abd.hWnd = hwnd; |
214 abd.hWnd = hwnd; |
| 219 abd.cbSize = sizeof(APPBARDATA); |
215 abd.cbSize = sizeof(APPBARDATA); |
| 220 abd.uEdge = ab->side; |
216 abd.uEdge = ab->side; |
| 221 |
217 |
| 222 iWidth = ab->docked_rect.right - ab->docked_rect.left; |
218 iWidth = ab->docked_rect.right - ab->docked_rect.left; |
| 223 |
219 |
| 224 abd.rc.top = rcWorkspace.top; |
220 abd.rc.top = rcWorkspace.top; |
| 225 abd.rc.bottom = rcWorkspace.bottom; |
221 abd.rc.bottom = rcWorkspace.bottom; |
| 226 switch (abd.uEdge) |
222 switch (abd.uEdge) |
| 227 { |
223 { |
| 228 case ABE_LEFT: |
224 case ABE_LEFT: |
| 286 long dockAreaWidth = 0; |
282 long dockAreaWidth = 0; |
| 287 |
283 |
| 288 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "wnd_moving\n"); |
284 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "wnd_moving\n"); |
| 289 |
285 |
| 290 GetCursorPos(&cp); |
286 GetCursorPos(&cp); |
| 291 monRect = get_rect_at_point(cp); |
287 get_rect_at_point(cp, &monRect); |
| 292 |
288 |
| 293 dockAreaWidth = (monRect.right - monRect.left) / 10; |
289 dockAreaWidth = (monRect.right - monRect.left) / 10; |
| 294 /* Which part of the screen are we in ? */ |
290 /* Which part of the screen are we in ? */ |
| 295 if (cp.x > (monRect.right - dockAreaWidth)) { |
291 if (cp.x > (monRect.right - dockAreaWidth)) { |
| 296 side = ABE_RIGHT; |
292 side = ABE_RIGHT; |
| 316 else if(side < 0) { |
312 else if(side < 0) { |
| 317 gtk_appbar_unregister(ab, msg->hwnd); |
313 gtk_appbar_unregister(ab, msg->hwnd); |
| 318 rc->bottom = rc->top + ab->undocked_height; |
314 rc->bottom = rc->top + ab->undocked_height; |
| 319 } |
315 } |
| 320 |
316 |
| 321 /* Switch to toolbar/regular caption*/ |
317 /* Switch to toolbar/regular caption*/ |
| 322 if(ab->docking) |
318 if(ab->docking) |
| 323 set_toolbar(msg->hwnd, TRUE); |
319 set_toolbar(msg->hwnd, TRUE); |
| 324 else if(!ab->docked) |
320 else if(!ab->docked) |
| 325 set_toolbar(msg->hwnd, FALSE); |
321 set_toolbar(msg->hwnd, FALSE); |
| 326 |
322 |
| 451 return GDK_FILTER_CONTINUE; |
447 return GDK_FILTER_CONTINUE; |
| 452 } |
448 } |
| 453 |
449 |
| 454 static GdkFilterReturn wnd_nchittest(GtkAppBar *ab, GdkXEvent *xevent) { |
450 static GdkFilterReturn wnd_nchittest(GtkAppBar *ab, GdkXEvent *xevent) { |
| 455 MSG *msg = (MSG*)xevent; |
451 MSG *msg = (MSG*)xevent; |
| 456 |
452 |
| 457 if(ab->docked) { |
453 if(ab->docked) { |
| 458 UINT ret = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam); |
454 UINT ret = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam); |
| 459 |
455 |
| 460 switch(ret) { |
456 switch(ret) { |
| 461 case HTBOTTOM: |
457 case HTBOTTOM: |
| 462 case HTBOTTOMLEFT: |
458 case HTBOTTOMLEFT: |
| 463 case HTBOTTOMRIGHT: |
459 case HTBOTTOMRIGHT: |
| 464 case HTTOP: |
460 case HTTOP: |
| 465 case HTTOPLEFT: |
461 case HTTOPLEFT: |
| 466 case HTTOPRIGHT: |
462 case HTTOPRIGHT: |
| 467 return GDK_FILTER_REMOVE; |
463 return GDK_FILTER_REMOVE; |
| 468 case HTLEFT: |
464 case HTLEFT: |
| 469 if(ab->side == ABE_LEFT) |
465 if(ab->side == ABE_LEFT) |
| 470 return GDK_FILTER_REMOVE; |
466 return GDK_FILTER_REMOVE; |
| 471 break; |
467 break; |
| 497 } |
493 } |
| 498 #endif |
494 #endif |
| 499 |
495 |
| 500 static GdkFilterReturn gtk_appbar_callback(GtkAppBar *ab, GdkXEvent *xevent) { |
496 static GdkFilterReturn gtk_appbar_callback(GtkAppBar *ab, GdkXEvent *xevent) { |
| 501 MSG *msg = (MSG*)xevent; |
497 MSG *msg = (MSG*)xevent; |
| 502 RECT orig; |
498 RECT orig, windowRect; |
| 503 |
499 |
| 504 switch (msg->wParam) { |
500 switch (msg->wParam) { |
| 505 case ABN_STATECHANGE: |
501 case ABN_STATECHANGE: |
| 506 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_callback: ABN_STATECHANGE\n"); |
502 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_callback: ABN_STATECHANGE\n"); |
| 507 break; |
503 break; |
| 517 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED); |
513 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED); |
| 518 } |
514 } |
| 519 } |
515 } |
| 520 |
516 |
| 521 break; |
517 break; |
| 522 |
518 case ABN_POSCHANGED: |
| 523 case ABN_POSCHANGED: |
519 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_callback: ABN_POSCHANGED\n"); |
| 524 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_callback: ABN_POSCHANGED\n"); |
520 CopyRect(&orig, &(ab->docked_rect)); |
| 525 CopyRect(&orig, &(ab->docked_rect)); |
521 get_rect_of_window(msg->hwnd, &windowRect); |
| 526 gtk_appbar_querypos(ab, msg->hwnd, get_rect_of_window(msg->hwnd)); |
522 gtk_appbar_querypos(ab, msg->hwnd, windowRect); |
| 527 if (EqualRect(&orig, &(ab->docked_rect)) == 0) { |
523 if (EqualRect(&orig, &(ab->docked_rect)) == 0) { |
| 528 MoveWindow(msg->hwnd, ab->docked_rect.left, ab->docked_rect.top, |
524 MoveWindow(msg->hwnd, ab->docked_rect.left, ab->docked_rect.top, |
| 529 ab->docked_rect.right - ab->docked_rect.left, |
525 ab->docked_rect.right - ab->docked_rect.left, |
| 530 ab->docked_rect.bottom - ab->docked_rect.top, TRUE); |
526 ab->docked_rect.bottom - ab->docked_rect.top, TRUE); |
| 531 } |
527 } |
| 532 gtk_appbar_setpos(ab, msg->hwnd); |
528 gtk_appbar_setpos(ab, msg->hwnd); |
| 533 break; |
529 break; |
| 534 #if 0 |
530 #if 0 |
| 535 default: |
531 default: |
| 536 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_callback: %d\n", msg->wParam); |
532 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_callback: %d\n", msg->wParam); |
| 537 #endif |
533 #endif |
| 538 } |
534 } |
| 575 } |
571 } |
| 576 return GDK_FILTER_CONTINUE; |
572 return GDK_FILTER_CONTINUE; |
| 577 } |
573 } |
| 578 |
574 |
| 579 void gtk_appbar_dock(GtkAppBar *ab, UINT side) { |
575 void gtk_appbar_dock(GtkAppBar *ab, UINT side) { |
| 580 RECT orig; |
576 RECT orig, windowRect; |
| 581 |
577 |
| 582 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_dock\n"); |
578 gaim_debug(GAIM_DEBUG_INFO, "gtkappbar", "gtk_appbar_dock\n"); |
| 583 |
579 |
| 584 if(!ab || !IsWindow(GDK_WINDOW_HWND(ab->win->window))) |
580 if(!ab || !IsWindow(GDK_WINDOW_HWND(ab->win->window))) |
| 585 return; |
581 return; |
| 586 |
582 |
| 587 ab->side = side; |
583 ab->side = side; |
| 588 get_window_normal_rc(GDK_WINDOW_HWND(ab->win->window), &(ab->docked_rect)); |
584 get_window_normal_rc(GDK_WINDOW_HWND(ab->win->window), &(ab->docked_rect)); |
| 589 CopyRect(&orig, &(ab->docked_rect)); |
585 CopyRect(&orig, &(ab->docked_rect)); |
| 590 gtk_appbar_querypos(ab, GDK_WINDOW_HWND(ab->win->window), |
586 get_rect_of_window(GDK_WINDOW_HWND(ab->win->window), &windowRect); |
| 591 get_rect_of_window(GDK_WINDOW_HWND(ab->win->window))); |
587 gtk_appbar_querypos(ab, GDK_WINDOW_HWND(ab->win->window), windowRect); |
| 592 if(EqualRect(&orig, &(ab->docked_rect)) == 0) |
588 if(EqualRect(&orig, &(ab->docked_rect)) == 0) |
| 593 MoveWindow(GDK_WINDOW_HWND(ab->win->window), |
589 MoveWindow(GDK_WINDOW_HWND(ab->win->window), |
| 594 ab->docked_rect.left, |
590 ab->docked_rect.left, |
| 595 ab->docked_rect.top, |
591 ab->docked_rect.top, |
| 596 ab->docked_rect.right - ab->docked_rect.left, |
592 ab->docked_rect.right - ab->docked_rect.left, |
| 597 ab->docked_rect.bottom - ab->docked_rect.top, TRUE); |
593 ab->docked_rect.bottom - ab->docked_rect.top, TRUE); |
| 598 gtk_appbar_setpos(ab, GDK_WINDOW_HWND(ab->win->window)); |
594 gtk_appbar_setpos(ab, GDK_WINDOW_HWND(ab->win->window)); |
| 599 set_toolbar(GDK_WINDOW_HWND(ab->win->window), TRUE); |
595 set_toolbar(GDK_WINDOW_HWND(ab->win->window), TRUE); |
| 600 ab->docked = TRUE; |
596 ab->docked = TRUE; |