Partially fix Excel 2007 and 2010 showing an extra taskbar icon when opening multiple documents in one instance.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/explorerframe/taskbarlist.c | 7 +++++-- dlls/explorerframe/tests/taskbarlist.c | 8 -------- dlls/winex11.drv/window.c | 26 ++++++++++++++++++++++++-- dlls/winex11.drv/x11drv.h | 4 +++- 4 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/dlls/explorerframe/taskbarlist.c b/dlls/explorerframe/taskbarlist.c index 6f24f359927..839ae210daa 100644 --- a/dlls/explorerframe/taskbarlist.c +++ b/dlls/explorerframe/taskbarlist.c @@ -25,6 +25,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(explorerframe);
+#define WM_WINE_DELETE_TAB (WM_USER + 1) + struct taskbar_list { ITaskbarList4 ITaskbarList4_iface; @@ -103,9 +105,10 @@ static HRESULT STDMETHODCALLTYPE taskbar_list_AddTab(ITaskbarList4 *iface, HWND
static HRESULT STDMETHODCALLTYPE taskbar_list_DeleteTab(ITaskbarList4 *iface, HWND hwnd) { - FIXME("iface %p, hwnd %p stub!\n", iface, hwnd); + TRACE("iface %p, hwnd %p\n", iface, hwnd);
- return E_NOTIMPL; + SendMessageW(GetDesktopWindow(), WM_WINE_DELETE_TAB, (WPARAM)hwnd, 0); + return S_OK; }
static HRESULT STDMETHODCALLTYPE taskbar_list_ActivateTab(ITaskbarList4 *iface, HWND hwnd) diff --git a/dlls/explorerframe/tests/taskbarlist.c b/dlls/explorerframe/tests/taskbarlist.c index ed1bc44a6ac..9b2de996000 100644 --- a/dlls/explorerframe/tests/taskbarlist.c +++ b/dlls/explorerframe/tests/taskbarlist.c @@ -55,7 +55,6 @@ static void test_ITaskbarList(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = ITaskbarList_DeleteTab(taskbarlist, hwnd); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
/* Call ITaskbarList::HrInit() */ @@ -88,7 +87,6 @@ static void test_ITaskbarList(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = ITaskbarList_DeleteTab(taskbarlist, hwnd); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
/* Test ITaskbarList::SetActiveAlt() */ @@ -116,7 +114,6 @@ static void test_ITaskbarList(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = ITaskbarList_DeleteTab(taskbarlist, hwnd); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
/* Test ITaskbarList::ActivateTab() */ @@ -144,21 +141,17 @@ static void test_ITaskbarList(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = ITaskbarList_DeleteTab(taskbarlist, hwnd); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
/* Test ITaskbarList::DeleteTab() */ /* Check invalid parameters */ hr = ITaskbarList_DeleteTab(taskbarlist, NULL); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = ITaskbarList_DeleteTab(taskbarlist, (HWND)0xdeadbeef); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = ITaskbarList_DeleteTab(taskbarlist, hwnd); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
/* Normal ITaskbarList::DeleteTab() */ @@ -167,7 +160,6 @@ static void test_ITaskbarList(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = ITaskbarList_DeleteTab(taskbarlist, hwnd); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
ref_count = ITaskbarList_Release(taskbarlist); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index bcb0b8044bc..dacb1293a9e 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -994,9 +994,9 @@ void update_net_wm_states( struct x11drv_win_data *data ) ex_style = GetWindowLongW( data->hwnd, GWL_EXSTYLE ); if (ex_style & WS_EX_TOPMOST) new_state |= (1 << NET_WM_STATE_ABOVE); - if (ex_style & (WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE)) + if (data->skip_taskbar || (ex_style & (WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE))) new_state |= (1 << NET_WM_STATE_SKIP_TASKBAR) | (1 << NET_WM_STATE_SKIP_PAGER); - if (!(ex_style & WS_EX_APPWINDOW) && GetWindow( data->hwnd, GW_OWNER )) + else if (!(ex_style & WS_EX_APPWINDOW) && GetWindow( data->hwnd, GW_OWNER )) new_state |= (1 << NET_WM_STATE_SKIP_TASKBAR);
if (!data->mapped) /* set the _NET_WM_STATE atom directly */ @@ -1858,6 +1858,7 @@ BOOL CDECL X11DRV_CreateDesktopWindow( HWND hwnd ) static WNDPROC desktop_orig_wndproc;
#define WM_WINE_NOTIFY_ACTIVITY WM_USER +#define WM_WINE_DELETE_TAB (WM_USER + 1)
static LRESULT CALLBACK desktop_wndproc_wrapper( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) { @@ -1877,6 +1878,9 @@ static LRESULT CALLBACK desktop_wndproc_wrapper( HWND hwnd, UINT msg, WPARAM wp, } break; } + case WM_WINE_DELETE_TAB: + SendMessageA( (HWND)wp, WM_X11DRV_DELETE_TAB, 0, 0 ); + break; } return desktop_orig_wndproc( hwnd, msg, wp, lp ); } @@ -2777,6 +2781,21 @@ done: return ret; }
+/* Delete a window from taskbar */ +static void taskbar_delete_tab( HWND hwnd ) +{ + struct x11drv_win_data *data; + + TRACE("hwnd %p\n", hwnd); + + data = get_win_data( hwnd ); + if (!data) + return; + + data->skip_taskbar = TRUE; + update_net_wm_states( data ); + release_win_data( data ); +}
/********************************************************************** * X11DRV_WindowMessage (X11DRV.@) @@ -2813,6 +2832,9 @@ LRESULT CDECL X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) return clip_cursor_notify( hwnd, (HWND)wp, (HWND)lp ); case WM_X11DRV_CLIP_CURSOR_REQUEST: return clip_cursor_request( hwnd, (BOOL)wp, (BOOL)lp ); + case WM_X11DRV_DELETE_TAB: + taskbar_delete_tab( hwnd ); + return 0; default: FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp ); return 0; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 4b4ee8daaeb..6a38fc5a20e 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -584,7 +584,8 @@ enum x11drv_window_messages WM_X11DRV_RESIZE_DESKTOP, WM_X11DRV_SET_CURSOR, WM_X11DRV_CLIP_CURSOR_NOTIFY, - WM_X11DRV_CLIP_CURSOR_REQUEST + WM_X11DRV_CLIP_CURSOR_REQUEST, + WM_X11DRV_DELETE_TAB };
/* _NET_WM_STATE properties that we keep track of */ @@ -619,6 +620,7 @@ struct x11drv_win_data BOOL shaped : 1; /* is window using a custom region shape? */ BOOL layered : 1; /* is window layered and with valid attributes? */ BOOL use_alpha : 1; /* does window use an alpha channel? */ + BOOL skip_taskbar : 1; /* does window should be deleted from taskbar */ int wm_state; /* current value of the WM_STATE property */ DWORD net_wm_state; /* bit mask of active x11drv_net_wm_state values */ Window embedder; /* window id of embedder */