[X11] Allow resizing with fixed borders

Windows can now be resized programmatically, even when they have
WindowBorder.Fixed. All resizing logic is now consolidated in the
Bounds property, and ConfigureNotify messages are now handled
correctly depending on their source (StructureNotify or
SubStructureNotify.)
This commit is contained in:
thefiddler 2013-12-27 11:07:38 +01:00
parent 4d27b6ee55
commit 6c6e09aae6

View file

@ -315,6 +315,11 @@ namespace OpenTK.Platform.X11
#region SetWindowMinMax #region SetWindowMinMax
void SetWindowMinMax(int min_width, int min_height, int max_width, int max_height)
{
SetWindowMinMax((short)min_width, (short)min_height, (short)max_width, (short)max_height);
}
void SetWindowMinMax(short min_width, short min_height, short max_width, short max_height) void SetWindowMinMax(short min_width, short min_height, short max_width, short max_height)
{ {
IntPtr dummy; IntPtr dummy;
@ -671,9 +676,30 @@ namespace OpenTK.Platform.X11
{ {
RefreshWindowBorders(); RefreshWindowBorders();
// For whatever reason, the x/y coordinates
// of a configure event are global to the
// root window when it is a send_event but
// local when it is a regular event.
// I don't know who designed this, but this is
// utter nonsense.
int x, y;
IntPtr unused;
if (!e.ConfigureEvent.send_event)
{
Functions.XTranslateCoordinates(window.Display,
window.Handle, window.RootWindow,
0, 0, out x, out y, out unused);
}
else
{
x = e.ConfigureEvent.x;
y = e.ConfigureEvent.y;
}
Point new_location = new Point( Point new_location = new Point(
e.ConfigureEvent.x - border_left, x - border_left,
e.ConfigureEvent.y - border_top); y - border_top);
if (Location != new_location) if (Location != new_location)
{ {
bounds.Location = new_location; bounds.Location = new_location;
@ -692,6 +718,8 @@ namespace OpenTK.Platform.X11
Resize(this, EventArgs.Empty); Resize(this, EventArgs.Empty);
} }
Debug.Print("[X11] Window bounds changed: {0}", bounds);
} }
static IntPtr CreateEmptyCursor(X11WindowInfo window) static IntPtr CreateEmptyCursor(X11WindowInfo window)
@ -951,17 +979,44 @@ namespace OpenTK.Platform.X11
public Rectangle Bounds public Rectangle Bounds
{ {
get { return bounds; } get
{
return bounds;
}
set set
{ {
bool is_location_changed = bounds.Location != value.Location;
bool is_size_changed = bounds.Size != value.Size;
int x = value.X;
int y = value.Y;
int width = value.Width - border_left - border_right;
int height = value.Height - border_top - border_bottom;
if (WindowBorder != WindowBorder.Resizable)
{
SetWindowMinMax(width, height, width, height);
}
using (new XLock(window.Display)) using (new XLock(window.Display))
{
if (is_location_changed && is_size_changed)
{ {
Functions.XMoveResizeWindow(window.Display, window.Handle, Functions.XMoveResizeWindow(window.Display, window.Handle,
value.X, x, y, width, height);
value.Y,
value.Width - border_left - border_right,
value.Height - border_top - border_bottom);
} }
else if (is_location_changed)
{
Functions.XMoveWindow(window.Display, window.Handle,
x, y);
}
else if (is_size_changed)
{
Functions.XResizeWindow(window.Display, window.Handle,
width, height);
}
}
ProcessEvents(); ProcessEvents();
} }
} }
@ -975,11 +1030,7 @@ namespace OpenTK.Platform.X11
get { return Bounds.Location; } get { return Bounds.Location; }
set set
{ {
using (new XLock(window.Display)) Bounds = new Rectangle(value, Bounds.Size);
{
Functions.XMoveWindow(window.Display, window.Handle, value.X, value.Y);
}
ProcessEvents();
} }
} }
@ -992,16 +1043,7 @@ namespace OpenTK.Platform.X11
get { return Bounds.Size; } get { return Bounds.Size; }
set set
{ {
int width = value.Width - border_left - border_right; Bounds = new Rectangle(Bounds.Location, value);
int height = value.Height - border_top - border_bottom;
width = width <= 0 ? 1 : width;
height = height <= 0 ? 1 : height;
using (new XLock(window.Display))
{
Functions.XResizeWindow(window.Display, window.Handle, width, height);
}
ProcessEvents();
} }
} }