Merge b0de49b280 into b4f73314a7
This commit is contained in:
commit
a12dfd3358
@ -114,6 +114,8 @@ public:
|
||||
virtual int y() { return 0; }
|
||||
virtual int w() { return 800; } // default, FL_OVERRIDE in driver!
|
||||
virtual int h() { return 600; } // default, FL_OVERRIDE in driver!
|
||||
virtual int x_from_right(int x) { return x * scale(0); }
|
||||
virtual int y_from_bottom(int y) { return y * scale(0); }
|
||||
virtual int screen_count();
|
||||
void screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my);
|
||||
virtual void screen_xywh(int &X, int &Y, int &W, int &H, int /*n*/) {
|
||||
|
||||
@ -58,6 +58,8 @@ private:
|
||||
protected:
|
||||
Fl_Window *pWindow;
|
||||
int screen_num_; // number of screen where window is mapped
|
||||
int win_gravity_;
|
||||
|
||||
public:
|
||||
Fl_Window_Driver(Fl_Window *);
|
||||
virtual ~Fl_Window_Driver();
|
||||
@ -69,6 +71,24 @@ public:
|
||||
int screen_num();
|
||||
void screen_num(int n) { screen_num_ = n; }
|
||||
|
||||
// Window gravity
|
||||
enum WIN_GRAVITY {
|
||||
WIN_GRAVITY_UNMAP = 0,
|
||||
WIN_GRAVITY_NORTHWEST = 1,
|
||||
WIN_GRAVITY_NORTH = 2,
|
||||
WIN_GRAVITY_NORTHEAST = 3,
|
||||
WIN_GRAVITY_WEST = 4,
|
||||
WIN_GRAVITY_CENTER = 5,
|
||||
WIN_GRAVITY_EAST = 6,
|
||||
WIN_GRAVITY_SOUTHWEST = 7,
|
||||
WIN_GRAVITY_SOUTH = 8,
|
||||
WIN_GRAVITY_SOUTHEAST = 9,
|
||||
WIN_GRAVITY_STATIC = 10,
|
||||
};
|
||||
/**
|
||||
Sets the desired window gravity. Almost certainly only useful in X11.
|
||||
*/
|
||||
virtual void win_gravity(int g) { win_gravity_ = g; }
|
||||
|
||||
// --- frequently used accessors to public window data
|
||||
/** returns the x coordinate of the window. */
|
||||
|
||||
@ -44,6 +44,7 @@ Fl_Window_Driver::Fl_Window_Driver(Fl_Window *win)
|
||||
wait_for_expose_value = 0;
|
||||
other_xid = 0;
|
||||
screen_num_ = 0;
|
||||
win_gravity_ = WIN_GRAVITY_STATIC;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -298,8 +298,38 @@ void Fl_Window::show(int argc, char **argv) {
|
||||
if (geometry) {
|
||||
int fl = 0, gx = x(), gy = y(); unsigned int gw = w(), gh = h();
|
||||
fl = Fl::screen_driver()->XParseGeometry(geometry, &gx, &gy, &gw, &gh);
|
||||
if (fl & Fl_Screen_Driver::fl_XNegative) gx = Fl::w()-w()+gx;
|
||||
if (fl & Fl_Screen_Driver::fl_YNegative) gy = Fl::h()-h()+gy;
|
||||
if (fl & Fl_Screen_Driver::fl_XNegative) gx = Fl::w()-gw+gx;
|
||||
if (fl & Fl_Screen_Driver::fl_YNegative) gy = Fl::h()-gh+gy;
|
||||
|
||||
// Determine window gravity from geometry. Note that negative X and Y
|
||||
// will only end up truly accurate if the screen scale is (or has been
|
||||
// set to) 1.0. This is because information about the actual screen
|
||||
// dimensions has been lost scaling integers.
|
||||
static const Fl_Window_Driver::WIN_GRAVITY gravity_table[16] = {
|
||||
Fl_Window_Driver::WIN_GRAVITY_STATIC,
|
||||
Fl_Window_Driver::WIN_GRAVITY_WEST,
|
||||
Fl_Window_Driver::WIN_GRAVITY_NORTH,
|
||||
Fl_Window_Driver::WIN_GRAVITY_NORTHWEST,
|
||||
Fl_Window_Driver::WIN_GRAVITY_STATIC,
|
||||
Fl_Window_Driver::WIN_GRAVITY_EAST,
|
||||
Fl_Window_Driver::WIN_GRAVITY_NORTH,
|
||||
Fl_Window_Driver::WIN_GRAVITY_NORTHEAST,
|
||||
Fl_Window_Driver::WIN_GRAVITY_STATIC,
|
||||
Fl_Window_Driver::WIN_GRAVITY_WEST,
|
||||
Fl_Window_Driver::WIN_GRAVITY_SOUTH,
|
||||
Fl_Window_Driver::WIN_GRAVITY_SOUTHWEST,
|
||||
Fl_Window_Driver::WIN_GRAVITY_STATIC,
|
||||
Fl_Window_Driver::WIN_GRAVITY_EAST,
|
||||
Fl_Window_Driver::WIN_GRAVITY_SOUTH,
|
||||
Fl_Window_Driver::WIN_GRAVITY_SOUTHEAST
|
||||
};
|
||||
int gravity_index = 0;
|
||||
gravity_index |= (fl & Fl_Screen_Driver::fl_XValue) ? 1 : 0;
|
||||
gravity_index |= (fl & Fl_Screen_Driver::fl_YValue) ? 2 : 0;
|
||||
gravity_index |= (fl & Fl_Screen_Driver::fl_XNegative) ? 4 : 0;
|
||||
gravity_index |= (fl & Fl_Screen_Driver::fl_YNegative) ? 8 : 0;
|
||||
pWindowDriver->win_gravity(gravity_table[gravity_index]);
|
||||
|
||||
// int mw,mh; minsize(mw,mh);
|
||||
// if (mw > gw) gw = mw;
|
||||
// if (mh > gh) gh = mh;
|
||||
|
||||
45
src/Fl_x.cxx
45
src/Fl_x.cxx
@ -2575,6 +2575,11 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
|
||||
int scr_x, scr_y, scr_w, scr_h;
|
||||
Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y, W, H);
|
||||
|
||||
#if 0
|
||||
// Munging the coordinates here just makes it impossible to put windows in
|
||||
// the right place. With win_gravity hints now being set, this should all
|
||||
// be down to the window manager.
|
||||
|
||||
if (win->border()) {
|
||||
// ensure border is on screen:
|
||||
// (assume extremely minimal dimensions for this border)
|
||||
@ -2592,6 +2597,7 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
|
||||
if (X < scr_x) X = scr_x;
|
||||
if (Y+H > scr_y+scr_h) Y = scr_y+scr_h-H;
|
||||
if (Y < scr_y) Y = scr_y;
|
||||
#endif
|
||||
}
|
||||
|
||||
// if the window is a subwindow and our parent is not mapped yet, we
|
||||
@ -2681,10 +2687,34 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
|
||||
s = Fl::screen_driver()->scale(nscreen);
|
||||
// if (!win->parent()) printf("win creation on screen #%d\n", nscreen);
|
||||
#endif
|
||||
|
||||
int win_x = rint(X*s);
|
||||
int win_y = rint(Y*s);
|
||||
|
||||
switch (Fl_X11_Window_Driver::driver(win)->win_gravity_) {
|
||||
case Fl_X11_Window_Driver::WIN_GRAVITY_NORTHEAST:
|
||||
case Fl_X11_Window_Driver::WIN_GRAVITY_EAST:
|
||||
case Fl_X11_Window_Driver::WIN_GRAVITY_SOUTHEAST:
|
||||
win_x = Fl::screen_driver()->x_from_right(X);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Fl_X11_Window_Driver::driver(win)->win_gravity_) {
|
||||
case Fl_X11_Window_Driver::WIN_GRAVITY_SOUTHWEST:
|
||||
case Fl_X11_Window_Driver::WIN_GRAVITY_SOUTH:
|
||||
case Fl_X11_Window_Driver::WIN_GRAVITY_SOUTHEAST:
|
||||
win_y = Fl::screen_driver()->y_from_bottom(Y);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Fl_X* xp =
|
||||
set_xid(win, XCreateWindow(fl_display,
|
||||
root,
|
||||
rint(X*s), rint(Y*s), W*s, H*s,
|
||||
win_x, win_y, W*s, H*s,
|
||||
0, // borderwidth
|
||||
visual->depth,
|
||||
InputOutput,
|
||||
@ -2849,7 +2879,18 @@ void Fl_X11_Window_Driver::sendxjunk() {
|
||||
hints->height_inc = 0;
|
||||
}
|
||||
|
||||
hints->win_gravity = StaticGravity;
|
||||
switch (win_gravity_) {
|
||||
case WIN_GRAVITY_NORTHWEST: hints->win_gravity = NorthWestGravity; break;
|
||||
case WIN_GRAVITY_NORTH: hints->win_gravity = NorthGravity; break;
|
||||
case WIN_GRAVITY_NORTHEAST: hints->win_gravity = NorthEastGravity; break;
|
||||
case WIN_GRAVITY_WEST: hints->win_gravity = WestGravity; break;
|
||||
case WIN_GRAVITY_CENTER: hints->win_gravity = CenterGravity; break;
|
||||
case WIN_GRAVITY_EAST: hints->win_gravity = EastGravity; break;
|
||||
case WIN_GRAVITY_SOUTHWEST: hints->win_gravity = SouthWestGravity; break;
|
||||
case WIN_GRAVITY_SOUTH: hints->win_gravity = SouthGravity; break;
|
||||
case WIN_GRAVITY_SOUTHEAST: hints->win_gravity = SouthEastGravity; break;
|
||||
default: hints->win_gravity = StaticGravity; break;
|
||||
}
|
||||
|
||||
// see the file /usr/include/X11/Xm/MwmUtil.h:
|
||||
// fill all fields to avoid bugs in kwm and perhaps other window managers:
|
||||
|
||||
@ -81,6 +81,8 @@ public:
|
||||
int y() FL_OVERRIDE;
|
||||
int w() FL_OVERRIDE;
|
||||
int h() FL_OVERRIDE;
|
||||
int x_from_right(int x) FL_OVERRIDE;
|
||||
int y_from_bottom(int y) FL_OVERRIDE;
|
||||
void screen_xywh(int &X, int &Y, int &W, int &H, int n) FL_OVERRIDE;
|
||||
void screen_dpi(float &h, float &v, int n=0) FL_OVERRIDE;
|
||||
void screen_work_area(int &X, int &Y, int &W, int &H, int n) FL_OVERRIDE;
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include <FL/Fl_Image_Surface.H>
|
||||
#include <FL/Fl_Tooltip.H>
|
||||
#include <FL/filename.H>
|
||||
#include <math.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "../../Fl_Timeout.h"
|
||||
@ -273,6 +274,22 @@ int Fl_X11_Screen_Driver::h() {
|
||||
;
|
||||
}
|
||||
|
||||
// Returns a real (unscaled) X coordinate calculated relative to the right of
|
||||
// of the screen. Used when positioning window with "east" gravity.
|
||||
|
||||
int Fl_X11_Screen_Driver::x_from_right(int x) {
|
||||
int dx = w() - x;
|
||||
return (fl_workarea_xywh[0] + fl_workarea_xywh[2]) - rint(dx * screens[0].scale);
|
||||
}
|
||||
|
||||
// Returns a real (unscaled) Y coordinate calculated relative to the bottom of
|
||||
// the screen. Used when positioning window with "south" gravity.
|
||||
|
||||
int Fl_X11_Screen_Driver::y_from_bottom(int y) {
|
||||
int dy = h() - y;
|
||||
return (fl_workarea_xywh[1] + fl_workarea_xywh[3]) - rint(dy * screens[0].scale);
|
||||
}
|
||||
|
||||
#define USE_XRANDR (HAVE_DLSYM && HAVE_DLFCN_H) // means attempt to dynamically load libXrandr.so
|
||||
#if USE_XRANDR
|
||||
#include <dlfcn.h>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user