Improve rescaling when window moved across screens: make sure center stays on new screen.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12367 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy 2017-07-30 16:21:57 +00:00
parent 5a7a954ebd
commit c4e04e4c7f
6 changed files with 23 additions and 32 deletions

View File

@ -262,15 +262,23 @@ bool Fl_Window_Driver::is_a_rescale_ = false;
void Fl_Window_Driver::resize_after_scale_change(int ns, float old_f, float new_f) {
screen_num(ns);
Fl_Graphics_Driver::default_driver().scale(new_f);
int X = pWindow->x()*old_f/new_f, Y = pWindow->y()*old_f/new_f;
int W, H;
if (pWindow->fullscreen_active()) {
W = pWindow->w() * old_f/new_f; H = pWindow->h() * old_f/new_f;
} else {
W = pWindow->w(); H = pWindow->h();
int sX, sY, sW, sH;
Fl::screen_xywh(sX, sY, sW, sH, ns); // bounding box of new screen
const int d = 5; // make sure new window centre is located in new screen
if (X+W/2 < sX) X = sX-W/2+d;
else if (X+W/2 > sX+sW-1) X = sX+sW-1-W/2-d;
if (Y+H/2 < sY) Y = sY-H/2+d;
else if (Y+H/2 > sY+sH-1) Y = sY+sH-1-H/2-d;
}
is_a_rescale_ = true;
size_range();
pWindow->resize(pWindow->x()*old_f/new_f, pWindow->y()*old_f/new_f, W, H);
pWindow->resize(X, Y, W, H);
is_a_rescale_ = false;
}

View File

@ -586,7 +586,8 @@ int Fl_WinAPI_Screen_Driver::get_mouse_unscaled(int &mx, int &my) {
POINT p;
GetCursorPos(&p);
mx = p.x; my = p.y;
return screen_num_unscaled(mx, my);
int screen = screen_num_unscaled(mx, my);
return screen >= 0 ? screen : 0;
}
int Fl_WinAPI_Screen_Driver::get_mouse(int &x, int &y) {
@ -1460,11 +1461,12 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
if (nx & 0x8000) nx -= 65536;
if (ny & 0x8000) ny -= 65536;
//fprintf(LOG,"WM_MOVE position(%d,%d) s=%.2f\n",int(nx/scale),int(ny/scale),scale);
// detect when window changes screen
// detect when window centre changes screen
Fl_WinAPI_Screen_Driver *sd = (Fl_WinAPI_Screen_Driver*)Fl::screen_driver();
int news = sd->screen_num_unscaled(nx + window->w()*scale/2, ny + window->h()*scale/2);
Fl_WinAPI_Window_Driver *wd = Fl_WinAPI_Window_Driver::driver(window);
int olds = wd->screen_num();
int news = sd->screen_num_unscaled(nx + window->w()*scale/2, ny + window->h()*scale/2);
if (news == -1) news = olds;
float s = sd->scale(news);
//fprintf(LOG,"WM_MOVE olds=%d(%.2f) news=%d(%.2f) busy=%d\n",olds, sd->scale(olds),news, s, Fl_WinAPI_Window_Driver::data_for_resize_window_between_screens_.busy);fflush(LOG);
if (olds != news) {

View File

@ -726,7 +726,8 @@ int Fl_X11_Screen_Driver::get_mouse_unscaled(int &mx, int &my) {
Window c; int cx,cy; unsigned int mask;
XQueryPointer(fl_display, root, &root, &c, &mx, &my, &cx, &cy, &mask);
#if USE_XFT
return screen_num_unscaled(mx, my);
int screen = screen_num_unscaled(mx, my);
return screen >= 0 ? screen : 0;
#else
return screen_num(mx, my);
#endif
@ -2015,12 +2016,12 @@ fprintf(stderr,"\n");*/
Window cr; int X, Y, W = actual.width, H = actual.height;
XTranslateCoordinates(fl_display, fl_xid(window), actual.root,
0, 0, &X, &Y, &cr);
#if USE_XFT // detect when window changes screen
int num = 0;
#if USE_XFT // detect when window centre changes screen
Fl_X11_Screen_Driver *d = (Fl_X11_Screen_Driver*)Fl::screen_driver();
num = d->screen_num_unscaled(X, Y, actual.width, actual.height);
Fl_X11_Window_Driver *wd = Fl_X11_Window_Driver::driver(window);
int olds = wd->screen_num();
int num = d->screen_num_unscaled(X+ actual.width/2, Y +actual.height/2);
if (num == -1) num = olds;
float s = d->scale(num);
if (num != olds) {
if (s != d->scale(olds) &&

View File

@ -666,9 +666,10 @@ void Fl_WinAPI_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &
}
}
//NOTICE: returns -1 if x,y is not in any screen
int Fl_WinAPI_Screen_Driver::screen_num_unscaled(int x, int y)
{
int screen = 0;
int screen = -1;
if (num_screens < 0) init();
for (int i = 0; i < num_screens; i ++) {
if (x >= screens[i].left && x < screens[i].right &&

View File

@ -56,7 +56,6 @@ public:
virtual void scale(int n, float f) { screens[n].scale = f;}
virtual float desktop_scale_factor();
int screen_num_unscaled(int x, int y);
int screen_num_unscaled(int x, int y, int w, int h);
#endif
static int ewmh_supported();

View File

@ -1182,9 +1182,10 @@ void Fl_X11_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &hei
}
#if USE_XFT
//NOTICE: returns -1 if x,y is not in any screen
int Fl_X11_Screen_Driver::screen_num_unscaled(int x, int y)
{
int screen = 0;
int screen = -1;
if (num_screens < 0) init();
for (int i = 0; i < num_screens; i ++) {
@ -1197,25 +1198,6 @@ int Fl_X11_Screen_Driver::screen_num_unscaled(int x, int y)
return screen;
}
int Fl_X11_Screen_Driver::screen_num_unscaled(int x, int y, int w, int h)
{
int best_screen = 0;
float best_intersection = 0.;
if (num_screens < 0) init();
for (int i = 0; i < num_screens; i++) {
float sintersection = fl_intersection(x, y, w, h, screens[i].x_org, screens[i].y_org,
screens[i].width, screens[i].height);
if (sintersection > best_intersection) {
best_screen = i;
best_intersection = sintersection;
}
}
return best_screen;
}
#endif
#if USE_XFT
#if HAVE_DLSYM && HAVE_DLFCN_H
// returns true when schema is among the list of available schemas
@ -1404,8 +1386,6 @@ float Fl_X11_Screen_Driver::desktop_scale_factor()
}
#endif // USE_XFT
//