Set window gravity hint correctly for X11

Removes some window positioning bodges, which mess with coordinates.
Window Managers should be responsible for placing windows correctly if
they're adding title bars and such to them.

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.

Updated patch fixes use of uninitialised variable, with help from
Albrecht Schlosser.
This commit is contained in:
Ciaran Anscomb 2023-08-14 11:59:20 +01:00
parent 336bd01f16
commit 570c0cce06
4 changed files with 69 additions and 1 deletions

View File

@ -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. */

View File

@ -43,6 +43,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;
}

View File

@ -284,6 +284,36 @@ void Fl_Window::show(int argc, char **argv) {
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;
// 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;

View File

@ -2375,6 +2375,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)
@ -2392,6 +2397,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
@ -2647,7 +2653,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: