dotgnu-pnet-commits
[Top][All Lists]
Advanced

[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"?





reply via email to

[Prev in Thread] Current Thread [Next in Thread]