Windows: remove necessity to compile with -DFLTK_HIDPI_SUPPORT to make WIN32 FLTK apps DPI-aware.
At this point, Windows FLTK apps detect HighDPI displays and rescale their GUI accordingly. They also all reply to ctrl/+/-/0/ keystrokes to enlarge/shrink/reset their windows. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12723 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
12f6285147
commit
7f78b1ef14
@ -55,9 +55,7 @@ extern FL_EXPORT struct Fl_XMap {
|
|||||||
COLORREF rgb; // this should be the type the RGB() macro returns
|
COLORREF rgb; // this should be the type the RGB() macro returns
|
||||||
HPEN pen; // pen, 0 if none created yet
|
HPEN pen; // pen, 0 if none created yet
|
||||||
int brush; // ref to solid brush, 0 if none created yet
|
int brush; // ref to solid brush, 0 if none created yet
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
|
||||||
int pwidth; // the width of the pen, if present
|
int pwidth; // the width of the pen, if present
|
||||||
#endif
|
|
||||||
} *fl_current_xmap;
|
} *fl_current_xmap;
|
||||||
inline COLORREF fl_RGB() {return fl_current_xmap->rgb;}
|
inline COLORREF fl_RGB() {return fl_current_xmap->rgb;}
|
||||||
inline HPEN fl_pen() {return fl_current_xmap->pen;}
|
inline HPEN fl_pen() {return fl_current_xmap->pen;}
|
||||||
|
@ -87,10 +87,8 @@ void fl_cleanup_dc_list(void);
|
|||||||
# include <wchar.h>
|
# include <wchar.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
typedef HRESULT(WINAPI * SetProcessDpiAwareness_type)(int);
|
||||||
typedef HRESULT(WINAPI * SetProcessDpiAwareness_type)(int);
|
static SetProcessDpiAwareness_type fl_SetProcessDpiAwareness = NULL;
|
||||||
static SetProcessDpiAwareness_type fl_SetProcessDpiAwareness = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern bool fl_clipboard_notify_empty(void);
|
extern bool fl_clipboard_notify_empty(void);
|
||||||
extern void fl_trigger_clipboard_notify(int source);
|
extern void fl_trigger_clipboard_notify(int source);
|
||||||
@ -522,7 +520,6 @@ void Fl_WinAPI_Screen_Driver::open_display_platform() {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
beenHereDoneThat = 1;
|
beenHereDoneThat = 1;
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
|
||||||
HMODULE hMod = LoadLibrary("Shcore.DLL");
|
HMODULE hMod = LoadLibrary("Shcore.DLL");
|
||||||
if (hMod) {
|
if (hMod) {
|
||||||
fl_SetProcessDpiAwareness = (SetProcessDpiAwareness_type)GetProcAddress(hMod, "SetProcessDpiAwareness");
|
fl_SetProcessDpiAwareness = (SetProcessDpiAwareness_type)GetProcAddress(hMod, "SetProcessDpiAwareness");
|
||||||
@ -533,14 +530,12 @@ void Fl_WinAPI_Screen_Driver::open_display_platform() {
|
|||||||
else fl_SetProcessDpiAwareness = NULL;
|
else fl_SetProcessDpiAwareness = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // FLTK_HIDPI_SUPPORT
|
|
||||||
OleInitialize(0L);
|
OleInitialize(0L);
|
||||||
|
|
||||||
get_imm_module();
|
get_imm_module();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
|
||||||
void Fl_WinAPI_Screen_Driver::init_screen_scale_factors() {
|
void Fl_WinAPI_Screen_Driver::init_screen_scale_factors() {
|
||||||
typedef HRESULT(WINAPI * GetDpiForMonitor_type)(HMONITOR, int, UINT *, UINT *);
|
typedef HRESULT(WINAPI * GetDpiForMonitor_type)(HMONITOR, int, UINT *, UINT *);
|
||||||
HMODULE hMod = LoadLibrary("Shcore.DLL");
|
HMODULE hMod = LoadLibrary("Shcore.DLL");
|
||||||
@ -558,7 +553,6 @@ void Fl_WinAPI_Screen_Driver::init_screen_scale_factors() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // FLTK_HIDPI_SUPPORT
|
|
||||||
|
|
||||||
|
|
||||||
class Fl_Win32_At_Exit {
|
class Fl_Win32_At_Exit {
|
||||||
@ -852,16 +846,9 @@ void Fl_WinAPI_System_Driver::paste(Fl_Widget &receiver, int clipboard, const ch
|
|||||||
int hdots = GetDeviceCaps(hdc, HORZRES);
|
int hdots = GetDeviceCaps(hdc, HORZRES);
|
||||||
ReleaseDC(NULL, hdc);
|
ReleaseDC(NULL, hdc);
|
||||||
float factor = (100.f * hmm) / hdots;
|
float factor = (100.f * hmm) / hdots;
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
|
||||||
float scaling = Fl::screen_driver()->scale(receiver.top_window()->driver()->screen_num());
|
float scaling = Fl::screen_driver()->scale(receiver.top_window()->driver()->screen_num());
|
||||||
width = int(width / (scaling * factor)); // convert to screen pixel unit
|
width = int(width / (scaling * factor)); // convert to screen pixel unit
|
||||||
height = int(height / (scaling * factor));
|
height = int(height / (scaling * factor));
|
||||||
#else
|
|
||||||
float scaling = ((Fl_WinAPI_Screen_Driver *)Fl::screen_driver())->DWM_scaling_factor();
|
|
||||||
width = int(width * scaling / factor); // convert to screen pixel unit
|
|
||||||
height = int(height * scaling / factor);
|
|
||||||
scaling = 1;
|
|
||||||
#endif
|
|
||||||
RECT rect = {0, 0, width, height};
|
RECT rect = {0, 0, width, height};
|
||||||
Fl_Image_Surface *surf = new Fl_Image_Surface(width, height, 1);
|
Fl_Image_Surface *surf = new Fl_Image_Surface(width, height, 1);
|
||||||
Fl_Surface_Device::push_current(surf);
|
Fl_Surface_Device::push_current(surf);
|
||||||
@ -1180,7 +1167,6 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
|||||||
if (window) {
|
if (window) {
|
||||||
switch (uMsg) {
|
switch (uMsg) {
|
||||||
|
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
|
||||||
case WM_DPICHANGED: { // 0x02E0
|
case WM_DPICHANGED: { // 0x02E0
|
||||||
if (fl_SetProcessDpiAwareness && !Fl_WinAPI_Window_Driver::data_for_resize_window_between_screens_.busy) {
|
if (fl_SetProcessDpiAwareness && !Fl_WinAPI_Window_Driver::data_for_resize_window_between_screens_.busy) {
|
||||||
RECT r;
|
RECT r;
|
||||||
@ -1193,7 +1179,6 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif // FLTK_HIDPI_SUPPORT
|
|
||||||
|
|
||||||
case WM_QUIT: // this should not happen?
|
case WM_QUIT: // this should not happen?
|
||||||
Fl::fatal("WM_QUIT message");
|
Fl::fatal("WM_QUIT message");
|
||||||
@ -2703,18 +2688,13 @@ void Fl_WinAPI_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image *&top
|
|||||||
ww /= scaling;
|
ww /= scaling;
|
||||||
if (wsides <= 1)
|
if (wsides <= 1)
|
||||||
ww = w() + 2 * wsides;
|
ww = w() + 2 * wsides;
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
|
||||||
float DWMscaling = scaling;
|
|
||||||
#else
|
|
||||||
float DWMscaling = ((Fl_WinAPI_Screen_Driver *)Fl::screen_driver())->DWM_scaling_factor();
|
|
||||||
#endif
|
|
||||||
// capture the 4 window sides from screen
|
// capture the 4 window sides from screen
|
||||||
Fl_WinAPI_Screen_Driver *dr = (Fl_WinAPI_Screen_Driver *)Fl::screen_driver();
|
Fl_WinAPI_Screen_Driver *dr = (Fl_WinAPI_Screen_Driver *)Fl::screen_driver();
|
||||||
if (htop) {
|
if (htop) {
|
||||||
r_top = dr->read_win_rectangle_unscaled(r.left, r.top, r.right - r.left, htop);
|
r_top = dr->read_win_rectangle_unscaled(r.left, r.top, r.right - r.left, htop);
|
||||||
top = Fl_Shared_Image::get(r_top);
|
top = Fl_Shared_Image::get(r_top);
|
||||||
if (DWMscaling != 1)
|
if (scaling != 1)
|
||||||
top->scale(ww, htop / DWMscaling, 0, 1);
|
top->scale(ww, htop / scaling, 0, 1);
|
||||||
}
|
}
|
||||||
if (wsides) {
|
if (wsides) {
|
||||||
r_left = dr->read_win_rectangle_unscaled(r.left, r.top + htop, wsides, h() * scaling);
|
r_left = dr->read_win_rectangle_unscaled(r.left, r.top + htop, wsides, h() * scaling);
|
||||||
|
@ -60,12 +60,8 @@ Fl_GDI_Copy_Surface_Driver::Fl_GDI_Copy_Surface_Driver(int w, int h) : Fl_Copy_S
|
|||||||
float factorw = (100.f * hmm) / hdots;
|
float factorw = (100.f * hmm) / hdots;
|
||||||
float factorh = (100.f * vmm) / vdots;
|
float factorh = (100.f * vmm) / vdots;
|
||||||
// Global display scaling factor: 1, 1.25, 1.5, 1.75, etc...
|
// Global display scaling factor: 1, 1.25, 1.5, 1.75, etc...
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
|
||||||
float scaling = Fl_Graphics_Driver::default_driver().scale();
|
float scaling = Fl_Graphics_Driver::default_driver().scale();
|
||||||
((Fl_GDI_Graphics_Driver*)driver())->scale(scaling);
|
((Fl_GDI_Graphics_Driver*)driver())->scale(scaling);
|
||||||
#else
|
|
||||||
float scaling = 1/((Fl_WinAPI_Screen_Driver*)Fl::screen_driver())->DWM_scaling_factor();
|
|
||||||
#endif
|
|
||||||
RECT rect; rect.left = 0; rect.top = 0; rect.right = (LONG)((w*scaling) * factorw); rect.bottom = (LONG)((h*scaling) * factorh);
|
RECT rect; rect.left = 0; rect.top = 0; rect.right = (LONG)((w*scaling) * factorw); rect.bottom = (LONG)((h*scaling) * factorh);
|
||||||
gc = CreateEnhMetaFile (NULL, NULL, &rect, NULL);
|
gc = CreateEnhMetaFile (NULL, NULL, &rect, NULL);
|
||||||
if (gc != NULL) {
|
if (gc != NULL) {
|
||||||
|
@ -86,9 +86,7 @@ static void set_xmap(Fl_XMap& xmap, COLORREF c, int lw) {
|
|||||||
// xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb); // get a pen into xmap.pen
|
// xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb); // get a pen into xmap.pen
|
||||||
LOGBRUSH penbrush = {BS_SOLID, xmap.rgb, 0};
|
LOGBRUSH penbrush = {BS_SOLID, xmap.rgb, 0};
|
||||||
xmap.pen = ExtCreatePen(PS_GEOMETRIC | PS_ENDCAP_FLAT | PS_JOIN_ROUND, lw, &penbrush, 0, 0);
|
xmap.pen = ExtCreatePen(PS_GEOMETRIC | PS_ENDCAP_FLAT | PS_JOIN_ROUND, lw, &penbrush, 0, 0);
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
|
||||||
xmap.pwidth = lw;
|
xmap.pwidth = lw;
|
||||||
#endif
|
|
||||||
xmap.brush = -1;
|
xmap.brush = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,11 +98,7 @@ void Fl_GDI_Graphics_Driver::color(Fl_Color i) {
|
|||||||
Fl_Graphics_Driver::color(i);
|
Fl_Graphics_Driver::color(i);
|
||||||
Fl_XMap &xmap = fl_xmap[i];
|
Fl_XMap &xmap = fl_xmap[i];
|
||||||
int tw = line_width_ ? line_width_ : int(scale_); if (!tw) tw = 1;
|
int tw = line_width_ ? line_width_ : int(scale_); if (!tw) tw = 1;
|
||||||
if (!xmap.pen
|
if (!xmap.pen || xmap.pwidth != tw) {
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
|
||||||
|| xmap.pwidth != tw
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
#if USE_COLORMAP
|
#if USE_COLORMAP
|
||||||
if (fl_palette) {
|
if (fl_palette) {
|
||||||
set_xmap(xmap, PALETTEINDEX(i), tw);
|
set_xmap(xmap, PALETTEINDEX(i), tw);
|
||||||
@ -126,11 +120,7 @@ void Fl_GDI_Graphics_Driver::color(uchar r, uchar g, uchar b) {
|
|||||||
COLORREF c = RGB(r,g,b);
|
COLORREF c = RGB(r,g,b);
|
||||||
Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) );
|
Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) );
|
||||||
int tw = line_width_ ? line_width_ : int(scale_); if (!tw) tw = 1;
|
int tw = line_width_ ? line_width_ : int(scale_); if (!tw) tw = 1;
|
||||||
if (!xmap.pen || c != xmap.rgb
|
if (!xmap.pen || c != xmap.rgb || tw != xmap.pwidth) {
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
|
||||||
|| tw != xmap.pwidth
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
clear_xmap(xmap);
|
clear_xmap(xmap);
|
||||||
set_xmap(xmap, c, tw);
|
set_xmap(xmap, c, tw);
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,7 @@ protected:
|
|||||||
static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM);
|
static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM);
|
||||||
BOOL screen_cb(HMONITOR mon, HDC, LPRECT r);
|
BOOL screen_cb(HMONITOR mon, HDC, LPRECT r);
|
||||||
int get_mouse_unscaled(int &mx, int &my);
|
int get_mouse_unscaled(int &mx, int &my);
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
|
||||||
void init_screen_scale_factors();
|
void init_screen_scale_factors();
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Fl_WinAPI_Screen_Driver() : Fl_Screen_Driver() {
|
Fl_WinAPI_Screen_Driver() : Fl_Screen_Driver() {
|
||||||
@ -86,7 +84,6 @@ public:
|
|||||||
virtual void disable_im();
|
virtual void disable_im();
|
||||||
virtual void open_display_platform();
|
virtual void open_display_platform();
|
||||||
virtual void offscreen_size(Fl_Offscreen off, int &width, int &height);
|
virtual void offscreen_size(Fl_Offscreen off, int &width, int &height);
|
||||||
#if defined(FLTK_HIDPI_SUPPORT)
|
|
||||||
virtual APP_SCALING_CAPABILITY rescalable() {
|
virtual APP_SCALING_CAPABILITY rescalable() {
|
||||||
return PER_SCREEN_APP_SCALING;
|
return PER_SCREEN_APP_SCALING;
|
||||||
}
|
}
|
||||||
@ -96,9 +93,6 @@ public:
|
|||||||
virtual void scale(int n, float f) {
|
virtual void scale(int n, float f) {
|
||||||
scale_of_screen[n] = f;
|
scale_of_screen[n] = f;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
float DWM_scaling_factor();
|
|
||||||
#endif
|
|
||||||
virtual float desktop_scale_factor();
|
virtual float desktop_scale_factor();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -600,32 +600,6 @@ Fl_RGB_Image *Fl_WinAPI_Screen_Driver::read_win_rectangle_unscaled(int X, int Y,
|
|||||||
return rgb;
|
return rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef FLTK_HIDPI_SUPPORT
|
|
||||||
/* Returns the current desktop scaling factor for screen_num (1.75 for example)
|
|
||||||
*/
|
|
||||||
float Fl_WinAPI_Screen_Driver::DWM_scaling_factor() {
|
|
||||||
// Compute the global desktop scaling factor: 1, 1.25, 1.5, 1.75, etc...
|
|
||||||
// This factor can be set in Windows 10 by
|
|
||||||
// "Change the size of text, apps and other items" in display settings.
|
|
||||||
// We don't cache this value because it can change while the app is running.
|
|
||||||
HDC hdc = GetDC(NULL);
|
|
||||||
int hr = GetDeviceCaps(hdc, HORZRES); // pixels visible to the app
|
|
||||||
#ifndef DESKTOPHORZRES
|
|
||||||
#define DESKTOPHORZRES 118
|
|
||||||
/* As of 27 august 2016, the DESKTOPHORZRES flag for GetDeviceCaps()
|
|
||||||
has disappeared from Microsoft online doc, but is quoted in numerous coding examples
|
|
||||||
e.g., https://social.msdn.microsoft.com/Forums/en-US/6acc3b21-23a4-4a00-90b4-968a43e1ccc8/capture-screen-with-high-dpi?forum=vbgeneral
|
|
||||||
It is necessary for the computation of the scaling factor at runtime as done here.
|
|
||||||
*/
|
|
||||||
#endif
|
|
||||||
int dhr = GetDeviceCaps(hdc, DESKTOPHORZRES); // true number of pixels on display
|
|
||||||
ReleaseDC(NULL, hdc);
|
|
||||||
float scaling = dhr/float(hr);
|
|
||||||
scaling = int(scaling * 100 + 0.5)/100.; // round to 2 digits after decimal point
|
|
||||||
return scaling;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // ! FLTK_HIDPI_SUPPORT
|
|
||||||
|
|
||||||
void Fl_WinAPI_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &height)
|
void Fl_WinAPI_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &height)
|
||||||
{
|
{
|
||||||
|
@ -103,16 +103,10 @@ RECT // frame of the decorated window in screen coordinates
|
|||||||
GetWindowRect(fl_xid(win), &r);
|
GetWindowRect(fl_xid(win), &r);
|
||||||
}
|
}
|
||||||
int width, height;
|
int width, height;
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
|
||||||
RECT rc;
|
RECT rc;
|
||||||
GetClientRect(fl_xid(win), &rc);
|
GetClientRect(fl_xid(win), &rc);
|
||||||
width = rc.right;
|
width = rc.right;
|
||||||
height = rc.bottom;
|
height = rc.bottom;
|
||||||
#else
|
|
||||||
float scaling = ((Fl_WinAPI_Screen_Driver*)Fl::screen_driver())->DWM_scaling_factor();
|
|
||||||
width = int(win->w() * scaling);
|
|
||||||
height = int(win->h() * scaling);
|
|
||||||
#endif
|
|
||||||
bx = (r.right - r.left - width)/2;
|
bx = (r.right - r.left - width)/2;
|
||||||
if (bx < 1) bx = 1;
|
if (bx < 1) bx = 1;
|
||||||
by = bx;
|
by = bx;
|
||||||
@ -137,14 +131,9 @@ int Fl_WinAPI_Window_Driver::decorated_h()
|
|||||||
{
|
{
|
||||||
int bt, bx, by;
|
int bt, bx, by;
|
||||||
border_width_title_bar_height(bx, by, bt);
|
border_width_title_bar_height(bx, by, bt);
|
||||||
#ifdef FLTK_HIDPI_SUPPORT
|
|
||||||
float s = Fl::screen_driver()->scale(screen_num());
|
float s = Fl::screen_driver()->scale(screen_num());
|
||||||
int mini_by = by/s; if (mini_by < 1) mini_by = 1;
|
int mini_by = by/s; if (mini_by < 1) mini_by = 1;
|
||||||
return h() + (bt + by)/s + mini_by;
|
return h() + (bt + by)/s + mini_by;
|
||||||
#else
|
|
||||||
float scaling = ((Fl_WinAPI_Screen_Driver*)Fl::screen_driver())->DWM_scaling_factor();
|
|
||||||
return h() + bt/scaling + 2 * by +1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,19 +84,6 @@ public:
|
|||||||
if( !pDataObj ) return E_INVALIDARG;
|
if( !pDataObj ) return E_INVALIDARG;
|
||||||
// set e_modifiers here from grfKeyState, set e_x and e_root_x
|
// set e_modifiers here from grfKeyState, set e_x and e_root_x
|
||||||
// check if FLTK handles this drag and return if it can't (i.e. BMP drag without filename)
|
// check if FLTK handles this drag and return if it can't (i.e. BMP drag without filename)
|
||||||
/* Tricky point here: Not DPI–aware applications use different units for the 'POINTL pt' argument
|
|
||||||
of the DragEnter, DragOver, and Drop member functions.
|
|
||||||
DragEnter receives the mouse coordinates in unscaled screen units,
|
|
||||||
whereas DragOver and Drop receive the mouse coordinates in scaled units.
|
|
||||||
|
|
||||||
DPI–aware applications transmit unscaled screen units to all 3 member functions.
|
|
||||||
These coordinates should be divided by the window's scale to get FLTK units.
|
|
||||||
*/
|
|
||||||
#ifndef FLTK_HIDPI_SUPPORT
|
|
||||||
POINT mp;
|
|
||||||
GetCursorPos(&mp); // bypass Windows bug that gives mouse coordinates in unscaled screen units
|
|
||||||
pt.x = mp.x; pt.y = mp.y;
|
|
||||||
#endif
|
|
||||||
POINT ppt;
|
POINT ppt;
|
||||||
Fl::e_x_root = ppt.x = pt.x;
|
Fl::e_x_root = ppt.x = pt.x;
|
||||||
Fl::e_y_root = ppt.y = pt.y;
|
Fl::e_y_root = ppt.y = pt.y;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user