Skip to content

Commit

Permalink
Make get_scroll_flags() multi-monitor aware
Browse files Browse the repository at this point in the history
  • Loading branch information
k-takata committed Oct 29, 2020
1 parent ff4669f commit 386fd82
Showing 1 changed file with 39 additions and 45 deletions.
84 changes: 39 additions & 45 deletions src/gui_w32.c
Original file line number Diff line number Diff line change
Expand Up @@ -2985,6 +2985,42 @@ gui_mch_flash(int msec)
InvertRect(s_hdc, &rc);
}

/*
* Check if the specified point is on-screen. (multi-monitor aware)
*/
static BOOL
is_point_onscreen(int x, int y)
{
POINT pt = {x, y};

return MonitorFromPoint(pt, MONITOR_DEFAULTTONULL) != NULL;
}

/*
* Check if the whole area of the specified window is on-screen.
*
* Note about DirectX: Windows 10 1809 or above no longer maintains image of
* the window portion that is off-screen. Scrolling by DWriteContext_Scroll()
* only works when the whole window is on-screen.
*/
static BOOL
is_window_onscreen(HWND hwnd)
{
RECT rc;

GetWindowRect(hwnd, &rc);

if (!is_point_onscreen(rc.left, rc.top))
return FALSE;
if (!is_point_onscreen(rc.left, rc.bottom))
return FALSE;
if (!is_point_onscreen(rc.right, rc.top))
return FALSE;
if (!is_point_onscreen(rc.right, rc.bottom))
return FALSE;
return TRUE;
}

/*
* Return flags used for scrolling.
* The SW_INVALIDATE is required when part of the window is covered or
Expand All @@ -2996,15 +3032,12 @@ get_scroll_flags(void)
HWND hwnd;
RECT rcVim, rcOther, rcDest;

GetWindowRect(s_hwnd, &rcVim);

// Check if the window is partly above or below the screen. We don't care
// about partly left or right of the screen, it is not relevant when
// scrolling up or down.
if (rcVim.top < 0 || rcVim.bottom > GetSystemMetrics(SM_CYFULLSCREEN))
// Check if the window is (partly) off-screen.
if (!is_window_onscreen(s_hwnd))
return SW_INVALIDATE;

// Check if there is an window (partly) on top of us.
GetWindowRect(s_hwnd, &rcVim);
for (hwnd = s_hwnd; (hwnd = GetWindow(hwnd, GW_HWNDPREV)) != (HWND)0; )
if (IsWindowVisible(hwnd))
{
Expand All @@ -3015,45 +3048,6 @@ get_scroll_flags(void)
return 0;
}

#if defined(FEAT_DIRECTX)
/*
* Check if the whole area of the specified window is on-screen.
* Windows 10 1809 or above no longer maintains image of the window portion
* that is off-screen. Scrolling by DWriteContext_Scroll() only works when
* the whole window is on-screen.
*/
static BOOL
is_window_onscreen(HWND hwnd)
{
RECT rc;
POINT pt;

GetWindowRect(hwnd, &rc);

pt.x = rc.left;
pt.y = rc.top;
if (MonitorFromPoint(pt, MONITOR_DEFAULTTONULL) == NULL)
return FALSE;

pt.x = rc.left;
pt.y = rc.bottom;
if (MonitorFromPoint(pt, MONITOR_DEFAULTTONULL) == NULL)
return FALSE;

pt.x = rc.right;
pt.y = rc.top;
if (MonitorFromPoint(pt, MONITOR_DEFAULTTONULL) == NULL)
return FALSE;

pt.x = rc.right;
pt.y = rc.bottom;
if (MonitorFromPoint(pt, MONITOR_DEFAULTTONULL) == NULL)
return FALSE;

return TRUE;
}
#endif

/*
* On some Intel GPUs, the regions drawn just prior to ScrollWindowEx()
* may not be scrolled out properly.
Expand Down

0 comments on commit 386fd82

Please sign in to comment.