4 |
|
|
5 |
Based on code copyright (C) 2004-2005 Martin Wickett |
Based on code copyright (C) 2004-2005 Martin Wickett |
6 |
|
|
7 |
Copyright 2005-2006 Peter Åstrand <astrand@cendio.se> for Cendio AB |
Copyright 2005-2008 Peter Åstrand <astrand@cendio.se> for Cendio AB |
8 |
Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB |
Copyright 2006-2008 Pierre Ossman <ossman@cendio.se> for Cendio AB |
9 |
|
|
10 |
This program is free software; you can redistribute it and/or modify |
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 |
it under the terms of the GNU General Public License as published by |
75 |
|
|
76 |
static HANDLE g_mutex = NULL; |
static HANDLE g_mutex = NULL; |
77 |
|
|
78 |
|
static BOOL is_toplevel(HWND hwnd) |
79 |
|
{ |
80 |
|
BOOL toplevel; |
81 |
|
HWND parent; |
82 |
|
parent = GetAncestor(hwnd, GA_PARENT); |
83 |
|
|
84 |
|
/* According to MS: "A window that has no parent, or whose |
85 |
|
parent is the desktop window, is called a top-level |
86 |
|
window." See http://msdn2.microsoft.com/en-us/library/ms632597(VS.85).aspx. */ |
87 |
|
toplevel = (!parent || parent == GetDesktopWindow()); |
88 |
|
return toplevel; |
89 |
|
} |
90 |
|
|
91 |
|
/* Determine the "parent" field for the CREATE response. */ |
92 |
|
static HWND |
93 |
|
get_parent(HWND hwnd) |
94 |
|
{ |
95 |
|
HWND result; |
96 |
|
HWND owner; |
97 |
|
LONG exstyle; |
98 |
|
|
99 |
|
/* Use the same logic to determine if the window should be |
100 |
|
"transient" (ie have no task icon) as MS uses. This is documented at |
101 |
|
http://msdn2.microsoft.com/en-us/library/bb776822.aspx */ |
102 |
|
owner = GetWindow(hwnd, GW_OWNER); |
103 |
|
exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); |
104 |
|
if (!owner && !(exstyle & WS_EX_TOOLWINDOW)) { |
105 |
|
/* display taskbar icon */ |
106 |
|
HWND parent; |
107 |
|
parent = GetAncestor(hwnd, GA_PARENT); |
108 |
|
if (parent == GetDesktopWindow()) { |
109 |
|
/* top-level without parent */ |
110 |
|
result = NULL; |
111 |
|
} else { |
112 |
|
result = parent; |
113 |
|
} |
114 |
|
} else { |
115 |
|
/* no taskbar icon */ |
116 |
|
result = (HWND) - 1; |
117 |
|
} |
118 |
|
|
119 |
|
return result; |
120 |
|
} |
121 |
|
|
122 |
static void |
static void |
123 |
update_position(HWND hwnd) |
update_position(HWND hwnd) |
124 |
{ |
{ |
188 |
vchannel_unblock(); |
vchannel_unblock(); |
189 |
} |
} |
190 |
|
|
|
static HWND |
|
|
get_parent(HWND hwnd) |
|
|
{ |
|
|
LONG style; |
|
|
HWND parent; |
|
|
|
|
|
style = GetWindowLong(hwnd, GWL_STYLE); |
|
|
|
|
|
if (style & (WS_POPUP | DS_MODALFRAME)) |
|
|
{ |
|
|
parent = (HWND) GetWindowLong(hwnd, GWL_HWNDPARENT); |
|
|
|
|
|
if (parent) |
|
|
{ |
|
|
style = GetWindowLong(parent, GWL_STYLE); |
|
|
if (((style & WS_CHILD) && !(style & WS_POPUP)) || !(style & WS_VISIBLE)) |
|
|
parent = NULL; |
|
|
} |
|
|
|
|
|
if (!parent) |
|
|
parent = GetWindow(hwnd, GW_OWNER); |
|
|
|
|
|
if (parent) |
|
|
{ |
|
|
style = GetWindowLong(parent, GWL_STYLE); |
|
|
if (((style & WS_CHILD) && !(style & WS_POPUP)) || !(style & WS_VISIBLE)) |
|
|
parent = NULL; |
|
|
} |
|
|
|
|
|
if (!parent) |
|
|
parent = (HWND) - 1; |
|
|
} |
|
|
else |
|
|
parent = NULL; |
|
|
|
|
|
return parent; |
|
|
} |
|
|
|
|
191 |
static HICON |
static HICON |
192 |
get_icon(HWND hwnd, int large) |
get_icon(HWND hwnd, int large) |
193 |
{ |
{ |
357 |
static LRESULT CALLBACK |
static LRESULT CALLBACK |
358 |
wndproc_hook_proc(int code, WPARAM cur_thread, LPARAM details) |
wndproc_hook_proc(int code, WPARAM cur_thread, LPARAM details) |
359 |
{ |
{ |
360 |
HWND hwnd, parent; |
HWND hwnd; |
361 |
UINT msg; |
UINT msg; |
362 |
WPARAM wparam; |
WPARAM wparam; |
363 |
LPARAM lparam; |
LPARAM lparam; |
374 |
|
|
375 |
style = GetWindowLong(hwnd, GWL_STYLE); |
style = GetWindowLong(hwnd, GWL_STYLE); |
376 |
|
|
377 |
/* Docs say that WS_CHILD and WS_POPUP is an illegal combination, |
if (!is_toplevel(hwnd)) { |
|
but they exist nonetheless. */ |
|
|
if ((style & WS_CHILD) && !(style & WS_POPUP)) |
|
378 |
goto end; |
goto end; |
379 |
|
} |
|
parent = get_parent(hwnd); |
|
380 |
|
|
381 |
switch (msg) |
switch (msg) |
382 |
{ |
{ |
399 |
flags |= SEAMLESS_CREATE_MODAL; |
flags |= SEAMLESS_CREATE_MODAL; |
400 |
|
|
401 |
vchannel_write("CREATE", "0x%08lx,0x%08lx,0x%08lx,0x%08x", |
vchannel_write("CREATE", "0x%08lx,0x%08lx,0x%08lx,0x%08x", |
402 |
(long) hwnd, (long) pid, (long) parent, |
(long) hwnd, (long) pid, (long) get_parent(hwnd), |
403 |
flags); |
flags); |
404 |
|
|
405 |
GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title)); |
GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title)); |
502 |
static LRESULT CALLBACK |
static LRESULT CALLBACK |
503 |
wndprocret_hook_proc(int code, WPARAM cur_thread, LPARAM details) |
wndprocret_hook_proc(int code, WPARAM cur_thread, LPARAM details) |
504 |
{ |
{ |
505 |
HWND hwnd, parent; |
HWND hwnd; |
506 |
UINT msg; |
UINT msg; |
507 |
WPARAM wparam; |
WPARAM wparam; |
508 |
LPARAM lparam; |
LPARAM lparam; |
519 |
|
|
520 |
style = GetWindowLong(hwnd, GWL_STYLE); |
style = GetWindowLong(hwnd, GWL_STYLE); |
521 |
|
|
522 |
/* Docs say that WS_CHILD and WS_POPUP is an illegal combination, |
if (!is_toplevel(hwnd)) { |
|
but they exist nonetheless. */ |
|
|
if ((style & WS_CHILD) && !(style & WS_POPUP)) |
|
523 |
goto end; |
goto end; |
524 |
|
} |
|
parent = get_parent(hwnd); |
|
525 |
|
|
526 |
switch (msg) |
switch (msg) |
527 |
{ |
{ |
577 |
{ |
{ |
578 |
/* FIXME: SetForegroundWindow() kills menus. Need to find a |
/* FIXME: SetForegroundWindow() kills menus. Need to find a |
579 |
clean way to solve this. */ |
clean way to solve this. */ |
580 |
if ((GetForegroundWindow() != hwnd) && !parent) |
if ((GetForegroundWindow() != hwnd) && !get_parent(hwnd)) |
581 |
SetForegroundWindow(hwnd); |
SetForegroundWindow(hwnd); |
582 |
|
|
583 |
vchannel_write("ACK", "%u", g_blocked_focus_serial); |
vchannel_write("ACK", "%u", g_blocked_focus_serial); |