Skip to content

Commit

Permalink
[UI] multi-monitor support extended for Windows' default clock toolti…
Browse files Browse the repository at this point in the history
…p [ci coverity]

* fixed multi-monitor clock spacing on Win8+ (we use different values on different platforms)
* fixed old multi-monitor clock hover code by reusing the main code
* allow PositionWindow() to center small windows within the clock's width (eg. tooltips)

Note: we should actually measure the real "show desktop" button dimensions... as HighDPI and future Windows versions might change it...
  • Loading branch information
White-Tiger committed Nov 6, 2015
1 parent b275751 commit 58bf9e7
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 58 deletions.
103 changes: 45 additions & 58 deletions src/DLL/Tclock.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,20 @@ void EndClock(HWND hwnd) //---------------------------------------------------
// PostMessage(g_hwndTClockMain,MAINM_EXIT,0,0);
_beginthread(SelfDestruct,0,hwnd);
}
static LRESULT CALLBACK HookedTooltip_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
(void)dwRefData;

switch(uMsg) {
case WM_DESTROY:
RemoveWindowSubclass(hwnd, HookedTooltip_Proc, uIdSubclass);
break;
case WM_WINDOWPOSCHANGING: {
WINDOWPOS* pwp = (WINDOWPOS*)lParam;
pwp->flags |= SWP_NOMOVE;
break;}
}
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
/*------------------------------------------------
subclass procedure of the clock
--------------------------------------------------*/
Expand Down Expand Up @@ -631,6 +645,8 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_TIMER: // Windows uses timer ID 0 to update every minute (tries to stay ~1 sec. close to full minute)
if(m_bNoClock) break;
return 0;
/* start of shared code used by multi-clock winproc
Use `gs_hwndClock` to refer to main clock, `hwnd` for triggering window*/
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
Expand All @@ -640,7 +656,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
SetForegroundWindow(gs_hwndTClockMain); // set T-Clock to foreground so we can open menus, etc.
if(m_BlinkState){
m_BlinkState=BLINK_NONE;
InvalidateRect(hwnd, NULL, 1);
InvalidateRect(gs_hwndClock, NULL, 1);
PostMessage(gs_hwndTClockMain,MAINM_BLINKOFF,0,0);
return 0;
}
Expand All @@ -657,22 +673,30 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
// return 0;
case WM_MOUSEMOVE:
if(!m_TipState){
TRACKMOUSEEVENT tme;
tme.cbSize=sizeof(TRACKMOUSEEVENT);
tme.dwFlags=TME_HOVER|TME_LEAVE;
tme.hwndTrack=hwnd;
tme.dwHoverTime=HOVER_DEFAULT;
TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT)};
tme.dwFlags = TME_HOVER|TME_LEAVE;
tme.hwndTrack = hwnd;
tme.dwHoverTime = HOVER_DEFAULT;
m_TipState = TrackMouseEvent(&tme);
FillClockBGHover(hwnd);
InvalidateRect(hwnd,NULL,0);
FillClockBGHover(gs_hwndClock);
InvalidateRect(gs_hwndClock, NULL, 0);
}
return 0;
case WM_MOUSEHOVER:
m_TipState = 2;
if(api.OS < TOS_VISTA || api.GetInt("Tooltip","bCustom",0)){
ShowTip(hwnd);//show custom tooltip
}else{
PostMessage(hwnd, WM_USER+103,1,0);//show system tooltip
SendMessage(gs_hwndClock, WM_USER+103,1,0);//show system tooltip
if(hwnd != gs_hwndClock) {
HWND tooltip = FindWindowEx(NULL, NULL, "ClockTooltipWindow", NULL);
if(tooltip) {
api.PositionWindow(tooltip, 0);
// hook to prevent any non-authorized move
// (Windows sometimes moves the tooltip for unknown reason)
SetWindowSubclass(tooltip, HookedTooltip_Proc, 0, 0);
}
}
}
return 0;
case WM_MOUSELEAVE:
Expand All @@ -681,13 +705,14 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if(api.OS < TOS_VISTA || api.GetInt("Tooltip","bCustom",0))
PostMessage(m_TipHwnd, TTM_TRACKACTIVATE , FALSE, (LPARAM)&m_TipInfo);//hide custom tooltip
else
PostMessage(hwnd, WM_USER+103,0,0);//hide system tooltip
PostMessage(gs_hwndClock, WM_USER+103,0,0);//hide system tooltip
}
m_TipState = 0;
FillClockBG(hwnd);
InvalidateRect(hwnd,NULL,0);
FillClockBG(gs_hwndClock);
InvalidateRect(gs_hwndClock,NULL,0);
}
return 0;
/* end of multi-clock shared code */
case WM_NCHITTEST: // original clock uses this message for context menu and hover, etc. and we need our own "handler"
// return HTTRANSPARENT; // Windows' clock uses this
// return HTCAPTION; // xD
Expand Down Expand Up @@ -765,18 +790,15 @@ LRESULT CALLBACK WndProcMultiClock(HWND hwnd, UINT message, WPARAM wParam, LPARA
{
switch(message){
case WM_NCCREATE:{
return 1;
}
return 1; }
case WM_CREATE:{
SetWindowLongPtr(hwnd, GWLP_ID, 303); // same ID as original clock
RegisterDragDrop(hwnd,m_droptarget); // setup DropFiles on sub-clock
return 0;
}
return 0; }
case WM_CLOSE:{
RevokeDragDrop(hwnd); // kill DropFiles on sub-clock
DestroyWindow(hwnd);
return 0;
}
return 0; }
case WM_WINDOWPOSCHANGING:{
return 0;}
case WM_WINDOWPOSCHANGED:
Expand All @@ -800,51 +822,16 @@ LRESULT CALLBACK WndProcMultiClock(HWND hwnd, UINT message, WPARAM wParam, LPARA
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_XBUTTONUP:
return SendMessage(gs_hwndClock,message,wParam,lParam);
// case WM_CONTEXTMENU:
// PostMessage(g_hwndTClockMain, message, wParam, lParam);
// return 0;
case WM_MOUSEMOVE:
if(!m_TipState){
TRACKMOUSEEVENT tme;
tme.cbSize=sizeof(TRACKMOUSEEVENT);
tme.dwFlags=TME_HOVER|TME_LEAVE;
tme.hwndTrack=hwnd;
tme.dwHoverTime=HOVER_DEFAULT;
m_TipState=1;
TrackMouseEvent(&tme);
FillClockBGHover(gs_hwndClock);
InvalidateRect(gs_hwndClock,NULL,0);
}
return 0;
case WM_MOUSEHOVER:
m_TipState=2;
if(api.OS < TOS_VISTA || api.GetInt("Tooltip","bCustom",0)){
ShowTip(hwnd);//show custom tooltip
}else{
SendMessage(gs_hwndClock, WM_USER+103,1,0);//show system tooltip
}
return 0;
case WM_MOUSELEAVE:
if(m_TipState){
if(m_TipState==2){
if(api.OS < TOS_VISTA || api.GetInt("Tooltip","bCustom",0))
PostMessage(m_TipHwnd, TTM_TRACKACTIVATE , FALSE, (LPARAM)&m_TipInfo);//hide custom tooltip
else
PostMessage(gs_hwndClock, WM_USER+103,0,0);//hide system tooltip
}
FillClockBG(gs_hwndClock);
InvalidateRect(gs_hwndClock,NULL,0);
}
m_TipState=0;
return 0;
return WndProc(hwnd, message, wParam, lParam);
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
/*------------------------------------------------
subclass procedure of the 2nd+ taskbar "worker" area (used to resize and allow own clock)
--------------------------------------------------*/
#define SHOW_DESKTOP_BUTTONSIZE 10
LRESULT CALLBACK WndProcMultiClockWorker(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message){
Expand Down Expand Up @@ -872,9 +859,9 @@ LRESULT CALLBACK WndProcMultiClockWorker(HWND hwnd, UINT message, WPARAM wParam,
m_multiClock[clock_id].workerRECT.right=pwp->cx;
m_multiClock[clock_id].workerRECT.bottom=pwp->cy;
if(pwp->cx > pwp->cy){ // horizontal
pwp->cx=pwp->cx-m_rcClock.right-SHOW_DESKTOP_BUTTONSIZE;
pwp->cx=pwp->cx-m_rcClock.right - api.desktop_button_size;
}else{
pwp->cy=pwp->cy-m_rcClock.bottom-SHOW_DESKTOP_BUTTONSIZE;
pwp->cy=pwp->cy-m_rcClock.bottom - api.desktop_button_size;
}
}
if(!(pwp->flags&SWP_NOMOVE)){
Expand All @@ -884,11 +871,11 @@ LRESULT CALLBACK WndProcMultiClockWorker(HWND hwnd, UINT message, WPARAM wParam,
cx=m_rcClock.right;
cy=m_rcClock.bottom;
if(m_multiClock[clock_id].workerRECT.right > m_multiClock[clock_id].workerRECT.bottom){ // horizontal
x=m_multiClock[clock_id].workerRECT.left+m_multiClock[clock_id].workerRECT.right-m_rcClock.right-SHOW_DESKTOP_BUTTONSIZE;
x=m_multiClock[clock_id].workerRECT.left+m_multiClock[clock_id].workerRECT.right-m_rcClock.right - api.desktop_button_size;
y=m_multiClock[clock_id].workerRECT.top+m_BORDER_MARGIN;
}else{
x=m_multiClock[clock_id].workerRECT.left+m_BORDER_MARGIN;
y=m_multiClock[clock_id].workerRECT.top+m_multiClock[clock_id].workerRECT.bottom-m_rcClock.bottom-SHOW_DESKTOP_BUTTONSIZE;
y=m_multiClock[clock_id].workerRECT.top+m_multiClock[clock_id].workerRECT.bottom-m_rcClock.bottom - api.desktop_button_size;
}
SetWindowPos(m_multiClock[clock_id].clock,0,x,y,cx,cy,0);
break;
Expand Down
8 changes: 8 additions & 0 deletions src/DLL/clock_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam);
TClockAPI api = {
NULL, // hInstance
0, // OS
10, // desktop_button_size
ms_root, // root
0, // root_len
// base
Expand Down Expand Up @@ -171,6 +172,13 @@ DLL_EXPORT int SetupClockAPI(int version, TClockAPI* _api){
if(!api.GetTickCount64)
api.GetTickCount64 = GetTickCount64_Wrapper;
}

if(gs_tos >= TOS_WIN10) {
api.desktop_button_size = 4+1;
} else if(gs_tos >= TOS_WIN8) {
api.desktop_button_size = 8;
} // default 10

if(_api) // NULL if internally called
memcpy(_api, &api, sizeof(TClockAPI));
return 0;
Expand Down
4 changes: 4 additions & 0 deletions src/DLL/clock_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ void Clock_PositionWindow(HWND hwnd, int padding) {
moni.rcMonitor.top=moni.rcWork.top+padding;
else // bottom
moni.rcMonitor.top=moni.rcWork.bottom-hProp-padding;
// center small windows within clock dimension when possible
GetClientRect(gs_hwndClock, &moni.rcWork);
if(wProp < moni.rcWork.right)
moni.rcMonitor.left -= ((moni.rcWork.right - wProp)>>1) + api.desktop_button_size;
}else if(moni.rcWork.left!=moni.rcMonitor.left || moni.rcWork.right!=moni.rcMonitor.right){ // vertical
moni.rcMonitor.top=moni.rcWork.bottom-hProp-padding;
if(moni.rcWork.left!=moni.rcMonitor.left) // left
Expand Down
1 change: 1 addition & 0 deletions src/common/clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct TClockAPI {
* \brief holds current OS version flags
* \sa TOS, TOS_2000, TOS_XP, TOS_XP_64, TOS_VISTA, TOS_WIN7, TOS_WIN8, TOS_WIN8_1, TOS_WIN10, TOS_NEWER, TOS_OLDER */
unsigned short OS;
unsigned short desktop_button_size; /**< size of the "show desktop" button (W7- 10px ?, W8 8px, W10 4+1px) */
const char* root; /**< our root folder path w/o ending slash */
size_t root_len; /**< length of our root folder path */

Expand Down

0 comments on commit 58bf9e7

Please sign in to comment.