[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Dotgnu-pnet-commits] pnetlib/Xsharp Display.cs, 1.17, 1.18 TopLevelWind
From: |
Rhys Weatherley <address@hidden> |
Subject: |
[Dotgnu-pnet-commits] pnetlib/Xsharp Display.cs, 1.17, 1.18 TopLevelWindow.cs, 1.18, 1.19 Xlib.cs.in, 1.23, 1.24 |
Date: |
Wed, 03 Dec 2003 05:14:23 +0000 |
Update of /cvsroot/dotgnu-pnet/pnetlib/Xsharp
In directory subversions:/tmp/cvs-serv23812/Xsharp
Modified Files:
Display.cs TopLevelWindow.cs Xlib.cs.in
Log Message:
Implement window maximize and restore; track dynamic changes to
the minimized and maximized window states.
Index: TopLevelWindow.cs
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnetlib/Xsharp/TopLevelWindow.cs,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -d -r1.18 -r1.19
*** TopLevelWindow.cs 3 Dec 2003 02:32:46 -0000 1.18
--- TopLevelWindow.cs 3 Dec 2003 05:14:21 -0000 1.19
***************
*** 38,41 ****
--- 38,42 ----
private String name;
private bool iconic;
+ private bool maximized;
private bool hasPrimaryFocus;
private bool reparented;
***************
*** 125,128 ****
--- 126,130 ----
this.name = ((name != null) ? name :
String.Empty);
this.iconic = false;
+ this.maximized = false;
this.hasPrimaryFocus = false;
this.reparented = false;
***************
*** 216,220 ****
EventMask.KeyReleaseMask |
EventMask.FocusChangeMask |
!
EventMask.StructureNotifyMask);
}
finally
--- 218,223 ----
EventMask.KeyReleaseMask |
EventMask.FocusChangeMask |
!
EventMask.StructureNotifyMask |
!
EventMask.PropertyChangeMask);
}
finally
***************
*** 352,355 ****
--- 355,410 ----
}
+ // Set the "_NET_WM_STATE" property, to include extended state requests.
+ private void SetNetState(IntPtr display, Xlib.Window handle)
+ {
+ Xlib.Xlong[] atoms = new Xlib.Xlong [8];
+ int numAtoms = 0;
+
+ // Determine if the window should be hidden
from the taskbar.
+ if((otherHints & OtherHints.HideFromTaskBar) !=
0)
+ {
+ atoms[numAtoms++] =
+ (Xlib.Xlong)Xlib.XInternAtom
+ (display,
"_NET_WM_STATE_SKIP_TASKBAR",
+ Xlib.Bool.False);
+ }
+
+ // Determine if the window should be made
top-most on-screen.
+ if((otherHints & OtherHints.TopMost) != 0)
+ {
+ atoms[numAtoms++] =
+ (Xlib.Xlong)Xlib.XInternAtom
+ (display,
"_NET_WM_STATE_ABOVE",
+ Xlib.Bool.False);
+ }
+
+ // Determine if the window should be maximized
by default.
+ if(maximized)
+ {
+ atoms[numAtoms++] =
+ (Xlib.Xlong)Xlib.XInternAtom
+ (display,
"_NET_WM_STATE_MAXIMIZED_VERT",
+ Xlib.Bool.False);
+ atoms[numAtoms++] =
+ (Xlib.Xlong)Xlib.XInternAtom
+ (display,
"_NET_WM_STATE_MAXIMIZED_HORZ",
+ Xlib.Bool.False);
+ }
+
+ // Update the "_NET_WM_STATE" property as
appropriate.
+ Xlib.Atom type = Xlib.XInternAtom
+ (display, "ATOM", Xlib.Bool.False);
+ if(numAtoms > 0)
+ {
+ Xlib.XChangeProperty
+ (display, handle,
dpy.wmNetState, type,
+ 32, 0 /* PropModeReplace */,
atoms, numAtoms);
+ }
+ else
+ {
+ Xlib.XDeleteProperty(display, handle,
dpy.wmNetState);
+ }
+ }
+
// Construct the XSizeHints structure for this window.
private XSizeHints BuildSizeHints(int x, int y, int width, int height)
***************
*** 493,496 ****
--- 548,583 ----
/// <summary>
+ /// <para>Determine if this widget is currently maximized.</para>
+ /// </summary>
+ ///
+ /// <value>
+ /// <para>Returns <see langword="true"/> if the widget is maximized;
+ /// <see langword="false"/> otherwise.</para>
+ /// </value>
+ ///
+ /// <remarks>
+ /// <para>Setting this property is equivalent to calling either
+ /// <c>Maximize</c> or <c>Restore</c>.</para>
+ /// </remarks>
+ public bool IsMaximized
+ {
+ get
+ {
+ return maximized;
+ }
+ set
+ {
+ if(value)
+ {
+ Maximize();
+ }
+ else
+ {
+ Restore();
+ }
+ }
+ }
+
+ /// <summary>
/// <para>Map this widget to the screen.</para>
/// </summary>
***************
*** 620,623 ****
--- 707,812 ----
}
+ // Send a maximize or restore message to the window manager.
+ private void SendMaximizeMessage
+ (IntPtr display, Xlib.Window handle, bool
maximize)
+ {
+ XEvent xevent;
+ xevent.xany.type =
(int)(EventType.ClientMessage);
+ xevent.xany.window = handle;
+ xevent.xclient.message_type = Xlib.XInternAtom
+ (display, "_NET_WM_STATE",
Xlib.Bool.False);
+ xevent.xclient.format = 32;
+ if(maximize)
+ {
+ xevent.xclient.setl(0, 1 /*
_NET_WM_STATE_ADD */ );
+ }
+ else
+ {
+ xevent.xclient.setl(0, 0 /*
_NET_WM_STATE_REMOVE */ );
+ }
+ Xlib.Atom atom1 = Xlib.XInternAtom
+ (display,
"_NET_WM_STATE_MAXIMIZED_VERT", Xlib.Bool.False);
+ Xlib.Atom atom2 = Xlib.XInternAtom
+ (display,
"_NET_WM_STATE_MAXIMIZED_HORZ", Xlib.Bool.False);
+ xevent.xclient.setl(1, (int)atom1);
+ xevent.xclient.setl(2, (int)atom2);
+ Xlib.XSendEvent
+ (display,
screen.RootWindow.GetWidgetHandle(),
+ Xlib.Bool.False,
(int)(EventMask.NoEventMask),
+ ref xevent);
+ }
+
+ /// <summary>
+ /// <para>Maximize this window.</para>
+ /// </summary>
+ public void Maximize()
+ {
+ try
+ {
+ IntPtr display = dpy.Lock();
+ if(!maximized)
+ {
+ if(firstMapDone)
+ {
+ // Send a "maximize"
message to the window manager,
+ // which will take care
of maximizing the window.
+ // Not all window
managers support this message.
+ SendMaximizeMessage
+ (display,
GetWidgetHandle(), true);
+ maximized = true;
+
OnMaximizedStateChanged(true);
+ }
+ else
+ {
+ // We haven't been
mapped for the first time yet,
+ // so merely update the
_NET_WM_STATE hint.
+ maximized = true;
+ SetNetState(display,
GetWidgetHandle());
+
OnMaximizedStateChanged(true);
+ }
+ }
+ }
+ finally
+ {
+ dpy.Unlock();
+ }
+ }
+
+ /// <summary>
+ /// <para>Restore this window from the maximized state.</para>
+ /// </summary>
+ public void Restore()
+ {
+ try
+ {
+ IntPtr display = dpy.Lock();
+ if(maximized)
+ {
+ if(firstMapDone)
+ {
+ // Send a "restore"
message to the window manager,
+ // which will take care
of restoring the window.
+ // Not all window
managers support this message.
+ SendMaximizeMessage
+ (display,
GetWidgetHandle(), false);
+ maximized = false;
+
OnMaximizedStateChanged(false);
+ }
+ else
+ {
+ // We haven't been
mapped for the first time yet,
+ // so merely update the
_NET_WM_STATE hint.
+ maximized = false;
+ SetNetState(display,
GetWidgetHandle());
+
OnMaximizedStateChanged(false);
+ }
+ }
+ }
+ finally
+ {
+ dpy.Unlock();
+ }
+ }
+
/// <summary>
/// <para>Close this window, as if the user had clicked the close box.
***************
*** 910,958 ****
if(!firstMapDone)
{
! data[0] =
Xlib.Xlong.Zero;
! data[1] =
Xlib.Xlong.Zero;
! if((value &
OtherHints.HideFromTaskBar) != 0)
! {
! data[0]
= (Xlib.Xlong)Xlib.XInternAtom
!
(display,
!
"_NET_WM_STATE_SKIP_TASKBAR",
!
Xlib.Bool.False);
! }
! if((value &
OtherHints.TopMost) != 0)
! {
! type =
Xlib.XInternAtom
!
(display,
!
"_NET_WM_STATE_ABOVE",
!
Xlib.Bool.False);
!
if(data[0] == Xlib.Xlong.Zero)
! {
!
data[0] = (Xlib.Xlong)type;
! }
! else
! {
!
data[1] = (Xlib.Xlong)type;
! }
! }
! wmType =
Xlib.XInternAtom
!
(display, "_NET_WM_STATE",
!
Xlib.Bool.False);
! if(data[0] !=
Xlib.Xlong.Zero &&
! data[1] !=
Xlib.Xlong.Zero)
! {
!
Xlib.XChangeProperty
!
(display, handle, wmType, wmAtom,
!
32, 0 /* PropModeReplace */, data, 2);
! }
! else if(data[0]
!= Xlib.Xlong.Zero)
! {
!
Xlib.XChangeProperty
!
(display, handle, wmType, wmAtom,
!
32, 0 /* PropModeReplace */, data, 1);
! }
! else
! {
!
Xlib.XDeleteProperty
!
(display, handle, wmType);
! }
}
}
--- 1099,1103 ----
if(!firstMapDone)
{
!
SetNetState(display, handle);
}
}
***************
*** 1224,1227 ****
--- 1369,1381 ----
/// <summary>
+ /// <para>Method that is called when the window's maximized state
+ /// changes.</para>
+ /// </summary>
+ protected virtual void OnMaximizedStateChanged(bool maximized)
+ {
+ // Nothing to do in this base class.
+ }
+
+ /// <summary>
/// <para>Method that is called when the window's close box is
/// clicked by the user.</para>
***************
*** 1370,1373 ****
--- 1524,1643 ----
}
+ // Get the contents of a 32-bit window property.
+ private Xlib.Xlong[] GetWindowProperty(Xlib.Atom name)
+ {
+ try
+ {
+ // Lock down the display and get the
window handle.
+ IntPtr display = dpy.Lock();
+ Xlib.Window handle = GetWidgetHandle();
+
+ // Fetch the value of the property.
+ Xlib.Atom actualTypeReturn;
+ Xlib.Xint actualFormatReturn;
+ Xlib.Xulong nitemsReturn;
+ Xlib.Xulong bytesAfterReturn;
+ IntPtr propReturn;
+ nitemsReturn = Xlib.Xulong.Zero;
+ if(Xlib.XGetWindowProperty
+ (display, handle, name,
0, 256,
+ Xlib.Bool.False,
Xlib.Atom.Zero,
+ out actualTypeReturn,
out actualFormatReturn,
+ out nitemsReturn, out
bytesAfterReturn,
+ out propReturn) ==
Xlib.Status.Zero)
+ {
+ if(((uint)bytesAfterReturn) > 0)
+ {
+ // We didn't get
everything, so try again.
+ if(propReturn !=
IntPtr.Zero)
+ {
+
Xlib.XFree(propReturn);
+ propReturn =
IntPtr.Zero;
+ }
+ int length = 256 +
(((int)bytesAfterReturn) / 4);
+ nitemsReturn =
Xlib.Xulong.Zero;
+
if(Xlib.XGetWindowProperty
+
(display, handle, name, 0, length,
+
Xlib.Bool.False, Xlib.Atom.Zero,
+ out
actualTypeReturn,
+ out
actualFormatReturn,
+ out
nitemsReturn, out bytesAfterReturn,
+ out
propReturn) != Xlib.Status.Zero)
+ {
+ propReturn =
IntPtr.Zero;
+ nitemsReturn =
Xlib.Xulong.Zero;
+ }
+ }
+ }
+ else
+ {
+ propReturn = IntPtr.Zero;
+ nitemsReturn = Xlib.Xulong.Zero;
+ }
+
+ // Convert the property data into an
array of longs.
+ Xlib.Xlong[] data = new Xlib.Xlong
[(int)nitemsReturn];
+ int size, posn;
+ unsafe
+ {
+ size = sizeof(Xlib.Xlong);
+ }
+ for(posn = 0; posn < (int)nitemsReturn;
++posn)
+ {
+ if(size == 4)
+ {
+ data[posn] =
(Xlib.Xlong)
+
Marshal.ReadInt32(propReturn, size * posn);
+ }
+ else if(size == 8)
+ {
+ data[posn] =
(Xlib.Xlong)
+
Marshal.ReadInt64(propReturn, size * posn);
+ }
+ }
+
+ // Free the property data.
+ if(propReturn != IntPtr.Zero)
+ {
+ Xlib.XFree(propReturn);
+ }
+
+ // Return the final data to the caller.
+ return data;
+ }
+ finally
+ {
+ dpy.Unlock();
+ }
+ }
+
+ // Determine if a property list contains a "maximized" state atom.
+ private bool ContainsMaximizedAtom(Xlib.Xlong[] list)
+ {
+ try
+ {
+ IntPtr display = dpy.Lock();
+ Xlib.Atom atom1 = Xlib.XInternAtom
+ (display,
"_NET_WM_STATE_MAXIMIZED_VERT",
+ Xlib.Bool.False);
+ Xlib.Atom atom2 = Xlib.XInternAtom
+ (display,
"_NET_WM_STATE_MAXIMIZED_HORZ",
+ Xlib.Bool.False);
+ foreach(Xlib.Xlong value in list)
+ {
+ if(atom1 == (Xlib.Atom)value ||
+ atom2 == (Xlib.Atom)value)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ finally
+ {
+ dpy.Unlock();
+ }
+ }
+
// Dispatch an event to this widget.
internal override void DispatchEvent(ref XEvent xevent)
***************
*** 1376,1379 ****
--- 1646,1650 ----
Widget widget;
InputOnlyWidget io;
+ Xlib.Xlong[] data;
switch((EventType)(xevent.xany.type__))
***************
*** 1399,1402 ****
--- 1670,1751 ----
// The user
pressed the "help" button.
OnHelp();
+ }
+ }
+ }
+ break;
+
+ case EventType.PropertyNotify:
+ {
+ // Handle a property change
notification.
+ if(xevent.xproperty.atom ==
dpy.wmState)
+ {
+ // The "WM_STATE"
property has changed.
+
if(xevent.xproperty.state == 0)
+ {
+ // New value
for the window state.
+ data =
GetWindowProperty(dpy.wmState);
+ if(data.Length
>= 1 && data[0] == (Xlib.Xlong)3)
+ {
+ // The
window is now in the iconic state.
+
if(!iconic)
+ {
+
iconic = true;
+
OnIconicStateChanged(true);
+ }
+ }
+ else
+ {
+ // The
window is now in the normal state.
+
if(iconic)
+ {
+
iconic = false;
+
OnIconicStateChanged(false);
+ }
+ }
+ }
+ else
+ {
+ // Property
removed, so it is "normal" now.
+ if(iconic)
+ {
+ iconic
= false;
+
OnIconicStateChanged(false);
+ }
+ }
+ }
+ else if(xevent.xproperty.atom
== dpy.wmNetState)
+ {
+ // The "_NET_WM_STATE"
property has changed.
+
if(xevent.xproperty.state == 0)
+ {
+ // New value:
look for maximized state atoms.
+ data =
GetWindowProperty(dpy.wmNetState);
+
if(ContainsMaximizedAtom(data))
+ {
+ // The
window is now maximized.
+
if(!maximized)
+ {
+
maximized = true;
+
OnMaximizedStateChanged(true);
+ }
+ }
+ else
+ {
+ // The
window has been restored.
+
if(maximized)
+ {
+
maximized = false;
+
OnMaximizedStateChanged(false);
+ }
+ }
+ }
+ else
+ {
+ // Value
removed, so not maximized any more.
+ if(maximized)
+ {
+
maximized = false;
+
OnMaximizedStateChanged(false);
+ }
}
}
Index: Xlib.cs.in
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnetlib/Xsharp/Xlib.cs.in,v
retrieving revision 1.23
retrieving revision 1.24
diff -C2 -d -r1.23 -r1.24
*** Xlib.cs.in 3 Dec 2003 02:32:46 -0000 1.23
--- Xlib.cs.in 3 Dec 2003 05:14:21 -0000 1.24
***************
*** 317,320 ****
--- 317,325 ----
@X_long@ mode);
+ [DllImport("X11")]
+ extern public static Status XSendEvent
+ (IntPtr display, Window w, Bool propagate,
+ @X_long@ event_mask, ref XEvent event_send);
+
// Declare GC-related external functions.
***************
*** 535,538 ****
--- 540,554 ----
extern public static @X_int@ XDeleteProperty
(IntPtr display, Window w, Atom property);
+
+ [DllImport("X11")]
+ extern public static Status XGetWindowProperty
+ (IntPtr display, Window w, Atom property,
+ @X_long@ long_offset, @X_long@ long_length,
+ Bool deleteProp, Atom req_type,
+ out Atom actual_type_return,
+ out Xlib.Xint actual_format_return,
+ out Xlib.Xulong nitems_return,
+ out Xlib.Xulong bytes_after_return,
+ out IntPtr prop_return);
// Text property and string functions.
Index: Display.cs
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnetlib/Xsharp/Display.cs,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -d -r1.17 -r1.18
*** Display.cs 3 Dec 2003 02:32:46 -0000 1.17
--- Display.cs 3 Dec 2003 05:14:21 -0000 1.18
***************
*** 55,58 ****
--- 55,60 ----
internal Xlib.Atom wmMwmHints;
internal Xlib.Atom wmContextHelp;
+ internal Xlib.Atom wmState;
+ internal Xlib.Atom wmNetState;
internal ButtonName selectButton;
internal ButtonName menuButton;
***************
*** 106,109 ****
--- 108,115 ----
wmContextHelp = Xlib.XInternAtom
(dpy, "_NET_WM_CONTEXT_HELP",
Xlib.Bool.False);
+ wmState = Xlib.XInternAtom
+ (dpy, "WM_STATE", Xlib.Bool.False);
+ wmNetState = Xlib.XInternAtom
+ (dpy, "_NET_WM_STATE", Xlib.Bool.False);
// Which buttons should we use for "Select" and
"Menu"?
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Dotgnu-pnet-commits] pnetlib/Xsharp Display.cs, 1.17, 1.18 TopLevelWindow.cs, 1.18, 1.19 Xlib.cs.in, 1.23, 1.24,
Rhys Weatherley <address@hidden> <=
- Prev by Date:
[Dotgnu-pnet-commits] pnetlib/System.Windows.Forms Control.cs, 1.47, 1.48 Form.cs, 1.25, 1.26
- Next by Date:
[Dotgnu-pnet-commits] pnetlib ChangeLog,1.1588,1.1589
- Previous by thread:
[Dotgnu-pnet-commits] pnetlib/System.Windows.Forms Control.cs, 1.47, 1.48 Form.cs, 1.25, 1.26
- Next by thread:
[Dotgnu-pnet-commits] pnetlib ChangeLog,1.1588,1.1589
- Index(es):