Commit 576e3b70 authored by Alexandre Julliard's avatar Alexandre Julliard

explorer: Merged systray support with the desktop window main loop.

Systray is now always available as part of the desktop and doesn't need to be started from shell32.
parent 1a4f6e57
......@@ -38,49 +38,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(systray);
const static WCHAR classname[] = /* Shell_TrayWnd */ {'S','h','e','l','l','_','T','r','a','y','W','n','d','\0'};
/* start timeout of 1 second */
#define SYSTRAY_START_TIMEOUT 1000
static BOOL start_systray_process(void)
{
STARTUPINFOW sinfo;
PROCESS_INFORMATION pinfo;
WCHAR command_line[] = {'e','x','p','l','o','r','e','r',' ','/','s','y','s','t','r','a','y',0};
static const WCHAR event_name[] = {'W','i','n','e','S','y','s','t','r','a','y','I','n','i','t','e','d',0};
HANDLE systray_ready_event;
DWORD wait;
TRACE("No tray window found, starting %s\n", debugstr_w(command_line));
ZeroMemory(&sinfo, sizeof(sinfo));
sinfo.cb = sizeof(sinfo);
if (CreateProcessW(NULL, command_line, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo) == 0)
{
ERR("Could not start %s, error 0x%lx\n", debugstr_w(command_line), GetLastError());
return FALSE;
}
CloseHandle(pinfo.hThread);
CloseHandle(pinfo.hProcess);
systray_ready_event = CreateEventW(NULL, TRUE, FALSE, event_name);
if (!systray_ready_event) return FALSE;
/* don't guess how long to wait, just wait for process to signal to us
* that it has created the Shell_TrayWnd class before continuing */
wait = WaitForSingleObject(systray_ready_event, SYSTRAY_START_TIMEOUT);
CloseHandle(systray_ready_event);
if (wait == WAIT_TIMEOUT)
{
ERR("timeout waiting for %s to start\n", debugstr_w(command_line));
return FALSE;
}
return TRUE;
}
/*************************************************************************
* Shell_NotifyIcon [SHELL32.296]
* Shell_NotifyIconA [SHELL32.297]
......@@ -126,16 +83,6 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
TRACE("dwMessage = %ld\n", dwMessage);
tray = FindWindowExW(0, NULL, classname, NULL);
/* this isn't how native does it - it assumes that Explorer is always
* running */
if (!tray)
{
if (!start_systray_process())
return FALSE;
tray = FindWindowExW(0, NULL, classname, NULL);
}
if (!tray) return FALSE;
cds.dwData = dwMessage;
......
......@@ -69,6 +69,9 @@ void manage_desktop(void)
SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)desktop_wnd_proc );
WINE_TRACE( "explorer starting on hwnd %p\n", hwnd );
initialize_systray();
while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg );
WINE_TRACE( "explorer exiting for hwnd %p\n", hwnd );
}
......@@ -24,15 +24,11 @@
#include <wine/debug.h>
#include "explorer_private.h"
#include <systray.h>
WINE_DEFAULT_DEBUG_CHANNEL(explorer);
unsigned int shell_refs = 0;
typedef struct parametersTAG {
BOOL explorer_mode;
BOOL systray_mode;
BOOL desktop_mode;
WCHAR root[MAX_PATH];
WCHAR selection[MAX_PATH];
......@@ -139,11 +135,6 @@ static void ParseCommandLine(LPSTR commandline,parameters_struct *parameters)
CopyPathRoot(parameters->root,
parameters->selection);
}
else if (strncmp(p,"systray",7)==0)
{
parameters->systray_mode = TRUE;
p+=7;
}
else if (strncmp(p,"desktop",7)==0)
{
parameters->desktop_mode = TRUE;
......@@ -159,44 +150,6 @@ static void ParseCommandLine(LPSTR commandline,parameters_struct *parameters)
}
}
static void do_systray_loop(void)
{
initialize_systray();
while (TRUE)
{
const int timeout = 5;
MSG message;
DWORD res;
res = MsgWaitForMultipleObjectsEx(0, NULL, shell_refs ? INFINITE : timeout * 1000,
QS_ALLINPUT, MWMO_WAITALL);
if (res == WAIT_TIMEOUT) break;
res = PeekMessage(&message, 0, 0, 0, PM_REMOVE);
if (!res) continue;
if (message.message == WM_QUIT)
{
WINE_FIXME("Somebody sent the shell a WM_QUIT message, should we reboot?");
/* Sending the tray window a WM_QUIT message is actually a
* tip given by some programming websites as a way of
* forcing a reboot! let's delay implementing this hack
* until we find a program that really needs it. for now
* just bail out.
*/
break;
}
TranslateMessage(&message);
DispatchMessage(&message);
}
shutdown_systray();
}
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE previnstance,
LPSTR cmdline,
......@@ -217,11 +170,6 @@ int WINAPI WinMain(HINSTANCE hinstance,
ParseCommandLine(cmdline,&parameters);
len = lstrlenW(winefile) +1;
if (parameters.systray_mode)
{
do_systray_loop();
return 0;
}
if (parameters.desktop_mode)
{
manage_desktop();
......
......@@ -22,5 +22,6 @@
#define __WINE_EXPLORER_PRIVATE_H
extern void manage_desktop(void);
extern void initialize_systray(void);
#endif /* __WINE_EXPLORER_PRIVATE_H */
......@@ -37,7 +37,7 @@
#include <wine/debug.h>
#include <wine/list.h>
#include "systray.h"
#include "explorer_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(systray);
......@@ -127,8 +127,8 @@ static LRESULT WINAPI adaptor_wndproc(HWND window, UINT msg,
ret = PostMessage(icon->owner, icon->callback_message, (WPARAM) icon->id, (LPARAM) msg);
if (!ret && (GetLastError() == ERROR_INVALID_HANDLE))
{
WINE_ERR("application window was destroyed without removing "
"notification icon, removing automatically\n");
WINE_WARN("application window was destroyed without removing "
"notification icon, removing automatically\n");
DestroyWindow(window);
}
return 0;
......@@ -140,9 +140,6 @@ static LRESULT WINAPI adaptor_wndproc(HWND window, UINT msg,
list_remove(&icon->entry);
DestroyIcon(icon->image);
HeapFree(GetProcessHeap(), 0, icon);
shell_refs--;
WINE_TRACE("shell now has %d refs\n", shell_refs);
break;
}
......@@ -236,9 +233,6 @@ static void add_icon(const NOTIFYICONDATAW *nid)
list_add_tail(&tray.icons, &icon->entry);
modify_icon(nid);
shell_refs++;
WINE_TRACE("shell now has %d refs\n", shell_refs);
}
static void delete_icon(const NOTIFYICONDATAW *nid)
......@@ -365,11 +359,9 @@ static BOOL is_systray_hidden(void)
void initialize_systray(void)
{
WNDCLASSEX class;
HANDLE event;
static const WCHAR classname[] = /* Shell_TrayWnd */ {'S','h','e','l','l','_','T','r','a','y','W','n','d',0};
static const WCHAR winname[] = /* Wine Systray Listener */
{'W','i','n','e',' ','S','y','s','t','r','a','y',' ','L','i','s','t','e','n','e','r',0};
static const WCHAR event_name[] = {'W','i','n','e','S','y','s','t','r','a','y','I','n','i','t','e','d',0};
WINE_TRACE("initiaizing\n");
......@@ -419,17 +411,4 @@ void initialize_systray(void)
WINE_ERR("Could not create tray window\n");
return;
}
/* tell shell32 that we're ready */
event = OpenEventW(EVENT_MODIFY_STATE, FALSE, event_name);
if (event)
{
SetEvent(event);
CloseHandle(event);
}
}
void shutdown_systray(void)
{
DestroyWindow(tray.window);
}
/*
* Copyright (C) 2004 Mike Hearn, for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
void initialize_systray(void);
void shutdown_systray(void);
/* when this drops to zero, a few seconds later the shell will shut down */
extern unsigned int shell_refs;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment