mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 23:25:45 +00:00
auto-hiding of inactive notification icons
svn path=/trunk/; revision=8807
This commit is contained in:
parent
5ac2148058
commit
f06e49faea
4 changed files with 162 additions and 36 deletions
|
@ -77,12 +77,15 @@ DELAYIMPORTS = oleaut32 wsock32
|
||||||
|
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
||||||
$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX)
|
$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) notifyhook.dll
|
||||||
$(LINK) $(LFLAGS) -o $@ $^ $(addprefix -l,$(LIBS)) $(addprefix -l,$(DELAYIMPORTS))
|
$(LINK) $(LFLAGS) -o $@ $^ $(addprefix -l,$(LIBS)) $(addprefix -l,$(DELAYIMPORTS))
|
||||||
|
|
||||||
explorer$(RES_SUFFIX): $(PROGRAM)_intres.rc res/*.bmp res/*.ico
|
explorer$(RES_SUFFIX): $(PROGRAM)_intres.rc res/*.bmp res/*.ico
|
||||||
windres $(RCFLAGS) -o $@ $(PROGRAM)_intres.rc
|
windres $(RCFLAGS) -o $@ $(PROGRAM)_intres.rc
|
||||||
|
|
||||||
|
notifyhook.dll: notifyhook/notifyhook.c notifyhook/notifyhook.h
|
||||||
|
$(CC) -D_WIN32_IE=0x0600 -Wall -D_NOTIFYHOOK_IMPL -Os -s notifyhook/notifyhook.c -shared -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(TARGET) $(OBJECTS) $(PROGRAM)$(RES_SUFFIX)
|
rm -f $(TARGET) $(OBJECTS) $(PROGRAM)$(RES_SUFFIX)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
- read "DESCRIPT.ION" files to display file descriptions
|
- read "DESCRIPT.ION" files to display file descriptions
|
||||||
- hiding of notification icons
|
|
||||||
- context menus for quick launch bar
|
- context menus for quick launch bar
|
||||||
- detect display mode changes and adjust desktop bar size
|
- detect display mode changes and adjust desktop bar size
|
||||||
- handling of full screen applications
|
- handling of full screen applications
|
||||||
|
|
|
@ -89,6 +89,9 @@ NotifyInfo::NotifyInfo()
|
||||||
_dwState = 0;
|
_dwState = 0;
|
||||||
_uCallbackMessage = 0;
|
_uCallbackMessage = 0;
|
||||||
_version = 0;
|
_version = 0;
|
||||||
|
|
||||||
|
_mode = NIM_AUTO;
|
||||||
|
_lastChange = GetTickCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -150,6 +153,9 @@ NotifyInfo& NotifyInfo::operator=(NOTIFYICONDATA* pnid)
|
||||||
_tipText.assign(txt, l);
|
_tipText.assign(txt, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///@todo test for real changes
|
||||||
|
_lastChange = GetTickCount();
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,6 +168,46 @@ NotifyArea::NotifyArea(HWND hwnd)
|
||||||
_clock_width = 0;
|
_clock_width = 0;
|
||||||
_last_icon_count = 0;
|
_last_icon_count = 0;
|
||||||
_show_hidden = false;
|
_show_hidden = false;
|
||||||
|
|
||||||
|
///@todo read from config file -->
|
||||||
|
NotifyIconConfig cfg;
|
||||||
|
|
||||||
|
cfg._tipText = TEXT("FRITZ!fon");
|
||||||
|
cfg._mode = NIM_HIDE;
|
||||||
|
_cfg.push_back(cfg);
|
||||||
|
|
||||||
|
cfg._tipText = TEXT("FRITZ!fax");
|
||||||
|
cfg._mode = NIM_HIDE;
|
||||||
|
_cfg.push_back(cfg);
|
||||||
|
|
||||||
|
cfg._tipText = TEXT("Volume");
|
||||||
|
cfg._mode = NIM_SHOW;
|
||||||
|
_cfg.push_back(cfg);
|
||||||
|
|
||||||
|
cfg._tipText.erase();
|
||||||
|
|
||||||
|
cfg._windowTitle = TEXT("Task Manager");
|
||||||
|
cfg._mode = NIM_SHOW;
|
||||||
|
_cfg.push_back(cfg);
|
||||||
|
|
||||||
|
cfg._windowTitle = TEXT("AntiVir");
|
||||||
|
cfg._mode = NIM_HIDE;
|
||||||
|
_cfg.push_back(cfg);
|
||||||
|
|
||||||
|
cfg._windowTitle = TEXT("Apache");
|
||||||
|
cfg._mode = NIM_HIDE;
|
||||||
|
_cfg.push_back(cfg);
|
||||||
|
|
||||||
|
cfg._windowTitle = TEXT("FRITZ!web");
|
||||||
|
cfg._mode = NIM_HIDE;
|
||||||
|
_cfg.push_back(cfg);
|
||||||
|
|
||||||
|
cfg._windowTitle.erase();
|
||||||
|
|
||||||
|
cfg._modulePath = TEXT("xyz"); //@@
|
||||||
|
cfg._mode = NIM_HIDE;
|
||||||
|
_cfg.push_back(cfg);
|
||||||
|
/// <--
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT NotifyArea::Init(LPCREATESTRUCT pcs)
|
LRESULT NotifyArea::Init(LPCREATESTRUCT pcs)
|
||||||
|
@ -257,10 +303,8 @@ LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
|
||||||
String path;
|
String path;
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
|
|
||||||
if (_hook.ModulePathCopyData(lparam, &hwnd, path)) {
|
if (_hook.ModulePathCopyData(lparam, &hwnd, path))
|
||||||
_window_modules[hwnd] = path;
|
_window_modules[hwnd] = path;
|
||||||
//@@ -> trigger DetermineHideState()
|
|
||||||
}
|
|
||||||
|
|
||||||
break;}
|
break;}
|
||||||
|
|
||||||
|
@ -357,7 +401,7 @@ LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pni
|
||||||
entry._idx = ++_next_idx;
|
entry._idx = ++_next_idx;
|
||||||
|
|
||||||
#if NOTIFYICON_VERSION>=3 // as of 21.08.2003 missing in MinGW headers
|
#if NOTIFYICON_VERSION>=3 // as of 21.08.2003 missing in MinGW headers
|
||||||
if (DetermineHideState(entry))
|
if (DetermineHideState(entry) && entry._mode==NIM_HIDE)
|
||||||
entry._dwState |= NIS_HIDDEN;
|
entry._dwState |= NIS_HIDDEN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -464,7 +508,7 @@ void NotifyArea::TimerTick()
|
||||||
bool do_refresh = false;
|
bool do_refresh = false;
|
||||||
|
|
||||||
// Look for task icons without valid owner window.
|
// Look for task icons without valid owner window.
|
||||||
// This is an advanced feature, which is missing in MS Windows.
|
// This is an extended feature missing in MS Windows.
|
||||||
for(NotifyIconSet::const_iterator it=_sorted_icons.begin(); it!=_sorted_icons.end(); ++it) {
|
for(NotifyIconSet::const_iterator it=_sorted_icons.begin(); it!=_sorted_icons.end(); ++it) {
|
||||||
const NotifyInfo& entry = *it;
|
const NotifyInfo& entry = *it;
|
||||||
|
|
||||||
|
@ -473,6 +517,40 @@ void NotifyArea::TimerTick()
|
||||||
++do_refresh;
|
++do_refresh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD now = GetTickCount();
|
||||||
|
|
||||||
|
// handle icon hiding
|
||||||
|
for(NotifyIconMap::iterator it=_icon_map.begin(); it!=_icon_map.end(); ++it) {
|
||||||
|
NotifyInfo& entry = it->second;
|
||||||
|
|
||||||
|
DetermineHideState(entry);
|
||||||
|
|
||||||
|
switch(entry._mode) {
|
||||||
|
case NIM_HIDE:
|
||||||
|
if (!(entry._dwState & NIS_HIDDEN)) {
|
||||||
|
entry._dwState |= NIS_HIDDEN;
|
||||||
|
++do_refresh;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NIM_SHOW:
|
||||||
|
if (entry._dwState&NIS_HIDDEN) {
|
||||||
|
entry._dwState &= ~NIS_HIDDEN;
|
||||||
|
++do_refresh;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NIM_AUTO:
|
||||||
|
// automatically hide icons after long periods of inactivity
|
||||||
|
if (!(entry._dwState & NIS_HIDDEN))
|
||||||
|
if (now-entry._lastChange > ICON_AUTOHIDE_SECONDS*1000) {
|
||||||
|
entry._dwState |= NIS_HIDDEN;
|
||||||
|
++do_refresh;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (do_refresh)
|
if (do_refresh)
|
||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
|
@ -499,44 +577,56 @@ NotifyIconSet::iterator NotifyArea::IconHitTest(const POINT& pos)
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if NOTIFYICON_VERSION>=3 // as of 21.08.2003 missing in MinGW headers
|
#if NOTIFYICON_VERSION>=3 // as of 21.08.2003 missing in MinGW headers
|
||||||
bool NotifyArea::DetermineHideState(NotifyInfo& entry)
|
|
||||||
|
bool NotifyIconConfig::match(const NotifyIconProps& props) const
|
||||||
{
|
{
|
||||||
if (entry._tipText == TEXT("FRITZ!fon"))
|
if (!_tipText.empty() && !props._tipText.empty())
|
||||||
return true;
|
if (props._tipText == _tipText)
|
||||||
|
|
||||||
if (entry._tipText == TEXT("FRITZ!fax"))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
TCHAR title[MAX_PATH];
|
|
||||||
|
|
||||||
if (GetWindowText(entry._hWnd, title, MAX_PATH)) {
|
|
||||||
if (_tcsstr(title, TEXT("Task Manager")))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (_tcsstr(title, TEXT("AntiVir")))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (_tcsstr(title, TEXT("Apache")))
|
if (!_windowTitle.empty() && !props._windowTitle.empty())
|
||||||
|
if (_tcsstr(props._windowTitle, _windowTitle))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (_tcsstr(title, TEXT("FRITZ!web")))
|
if (!_modulePath.empty() && !props._modulePath.empty())
|
||||||
|
if (!_tcsicmp(props._modulePath, _modulePath))
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
const String& modulePath = _window_modules[entry._hWnd];
|
|
||||||
|
|
||||||
// request module path for new windows (We will get an asynchronous answer by a WM_COPYDATA message.)
|
|
||||||
if (modulePath.empty()) {
|
|
||||||
_hook.GetModulePath(entry._hWnd, _hwnd);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modulePath == TEXT("xyz")) //@@
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NotifyArea::DetermineHideState(NotifyInfo& entry)
|
||||||
|
{
|
||||||
|
for(NotifyIconCfgList::const_iterator it=_cfg.begin(); it!=_cfg.end(); ++it) {
|
||||||
|
const NotifyIconConfig& cfg = *it;
|
||||||
|
|
||||||
|
NotifyIconProps props;
|
||||||
|
|
||||||
|
props._tipText = entry._tipText;
|
||||||
|
|
||||||
|
TCHAR title[MAX_PATH];
|
||||||
|
if (GetWindowText(entry._hWnd, title, MAX_PATH))
|
||||||
|
props._windowTitle = title;
|
||||||
|
|
||||||
|
const String& modulePath = _window_modules[entry._hWnd];
|
||||||
|
|
||||||
|
// request module path for new windows (We will get an asynchronous answer by a WM_COPYDATA message.)
|
||||||
|
if (!modulePath.empty())
|
||||||
|
props._modulePath = modulePath;
|
||||||
|
else
|
||||||
|
_hook.GetModulePath(entry._hWnd, _hwnd);
|
||||||
|
|
||||||
|
if (cfg.match(props)) {
|
||||||
|
entry._mode = cfg._mode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
|
|
||||||
#define PM_GETMODULEPATH_CB (WM_APP+0x21)
|
#define PM_GETMODULEPATH_CB (WM_APP+0x21)
|
||||||
|
|
||||||
|
#define ICON_AUTOHIDE_SECONDS 300
|
||||||
|
|
||||||
|
|
||||||
/// NotifyIconIndex is used for maintaining the order of notification icons.
|
/// NotifyIconIndex is used for maintaining the order of notification icons.
|
||||||
struct NotifyIconIndex
|
struct NotifyIconIndex
|
||||||
|
@ -54,7 +56,34 @@ protected:
|
||||||
NotifyIconIndex();
|
NotifyIconIndex();
|
||||||
};
|
};
|
||||||
|
|
||||||
/// structure for maintaining informations of one notification icons
|
|
||||||
|
enum NOTIFYICONMODE {
|
||||||
|
NIM_AUTO, NIM_SHOW, NIM_HIDE
|
||||||
|
};
|
||||||
|
|
||||||
|
/// properties used to identify a notification icon
|
||||||
|
struct NotifyIconProps
|
||||||
|
{
|
||||||
|
String _tipText;
|
||||||
|
String _windowTitle; // To look at the window title and at the window module path of the notify icon owner window
|
||||||
|
String _modulePath; // to identify notification icons is an extension above XP's behaviour.
|
||||||
|
}; // (XP seems to store icon image data in the registry instead.)
|
||||||
|
|
||||||
|
/// configuration for the display mode of a notification icon
|
||||||
|
struct NotifyIconConfig : public NotifyIconProps
|
||||||
|
{
|
||||||
|
NotifyIconConfig() : _mode(NIM_AUTO) {}
|
||||||
|
|
||||||
|
bool match(const NotifyIconProps& props) const;
|
||||||
|
|
||||||
|
NOTIFYICONMODE _mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// list of NotifyIconConfig structures
|
||||||
|
typedef list<NotifyIconConfig> NotifyIconCfgList;
|
||||||
|
|
||||||
|
|
||||||
|
/// structure for maintaining informations about one notification icon
|
||||||
struct NotifyInfo : public NotifyIconIndex
|
struct NotifyInfo : public NotifyIconIndex
|
||||||
{
|
{
|
||||||
NotifyInfo();
|
NotifyInfo();
|
||||||
|
@ -71,6 +100,9 @@ struct NotifyInfo : public NotifyIconIndex
|
||||||
UINT _uCallbackMessage;
|
UINT _uCallbackMessage;
|
||||||
UINT _version;
|
UINT _version;
|
||||||
String _tipText;
|
String _tipText;
|
||||||
|
|
||||||
|
NOTIFYICONMODE _mode;
|
||||||
|
DWORD _lastChange; // timer tick value of the last change
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef map<NotifyIconIndex, NotifyInfo> NotifyIconMap;
|
typedef map<NotifyIconIndex, NotifyInfo> NotifyIconMap;
|
||||||
|
@ -127,6 +159,8 @@ protected:
|
||||||
NotifyIconSet::iterator IconHitTest(const POINT& pos);
|
NotifyIconSet::iterator IconHitTest(const POINT& pos);
|
||||||
bool DetermineHideState(NotifyInfo& entry);
|
bool DetermineHideState(NotifyInfo& entry);
|
||||||
|
|
||||||
|
NotifyIconCfgList _cfg;
|
||||||
|
|
||||||
NotifyHook _hook;
|
NotifyHook _hook;
|
||||||
map<HWND, String> _window_modules;
|
map<HWND, String> _window_modules;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue