+2006-11-29 Chris Toshok <toshok@ximian.com>
+
+ * X11Hwnd.cs: implement GetWindowTransparency, and also add
+ caching for WINDOW_TYPE and _NET_WM_WINDOW_OPACITY. We invalidate
+ the cache when we get a PropertyNotify on that atom.
+
+ * X11Display.cs: return GetSet from SupportsTransparency if we
+ have a compositor running. otherwise return None.
+
+ * XplatUIX11-new.cs: pass SupportsTransparency off onto the
+ X11Display, and pass GetWindowTransparency off onto the X11Hwnd.
+
2006-11-29 Chris Toshok <toshok@ximian.com>
* X11ThreadQueue.cs (EnqueueUnlocked): add the switch motionnotify
}
}
- public bool SupportsTransparency ()
+ public TransparencySupport SupportsTransparency ()
{
// compiz adds _NET_WM_WINDOW_OPACITY to _NET_SUPPORTED on the root window, check for that
- return ((IList)root_hwnd._NET_SUPPORTED).Contains (Atoms._NET_WM_WINDOW_OPACITY);
+ return ((IList)root_hwnd._NET_SUPPORTED).Contains (Atoms._NET_WM_WINDOW_OPACITY) ? TransparencySupport.GetSet : TransparencySupport.None;
}
public void SendAsyncMethod (AsyncMethodData method)
{
X11Display display;
- bool refetch_wm_state = true;
+ bool refetch_window_type = true;
+ bool refetch_window_opacity = true;
+
IntPtr[] wm_state = new IntPtr[0];
IntPtr[] window_type = new IntPtr[0];
+ double trans = 1.0;
string text;
X11ThreadQueue queue;
{
if (xevent.PropertyEvent.atom == display.Atoms._NET_WM_WINDOW_TYPE) {
// we need to recache our WINDOW_TYPE on the next query
+ refetch_window_type = true;
+ window_type = null;
}
else if (xevent.PropertyEvent.atom == display.Atoms._NET_WM_STATE) {
// we need to recache our WM_STATE on the next query
// update our Text property
}
else if (xevent.PropertyEvent.atom == display.Atoms._NET_WM_WINDOW_OPACITY) {
- // update the Hwnd's opacity
+ // we need to recache our _NET_WM_WINDOW_OPACITY on the next query.
+ refetch_window_opacity = true;
}
// else we don't care about it
+
}
public void SetIcon (Icon icon)
PropertyMode.Replace, data, size);
}
+ public double GetWindowTransparency ()
+ {
+ if (refetch_window_opacity) {
+ trans = 1.0;
+
+ IntPtr actual_atom;
+ int actual_format;
+ IntPtr nitems;
+ IntPtr bytes_after;
+ IntPtr prop = IntPtr.Zero;
+
+ IntPtr w = WholeWindow;
+ if (reparented)
+ w = display.XGetParent (WholeWindow);
+
+ Xlib.XGetWindowProperty (display.Handle, w,
+ display.Atoms._NET_WM_WINDOW_OPACITY, IntPtr.Zero, new IntPtr (16), false,
+ display.Atoms.XA_CARDINAL,
+ out actual_atom, out actual_format, out nitems, out bytes_after, ref prop);
+
+ if (((long)nitems == 1) && (prop != IntPtr.Zero)) {
+ int x11_opacity = Marshal.ReadInt32(prop, 0);
+ trans = ((double)x11_opacity) / 0xffffffff;
+ }
+
+ if (prop != IntPtr.Zero) {
+ Xlib.XFree(prop);
+ }
+ }
+
+ return trans;
+ }
public void SetWindowTransparency (double transparency, Color key)
{
public void FrameExtents (out int left, out int top)
{
- IntPtr actual_atom;
- int actual_format;
- IntPtr nitems;
- IntPtr bytes_after;
- IntPtr prop = IntPtr.Zero;
+ IntPtr actual_atom;
+ int actual_format;
+ IntPtr nitems;
+ IntPtr bytes_after;
+ IntPtr prop = IntPtr.Zero;
Xlib.XGetWindowProperty (display.Handle, WholeWindow,
display.Atoms._NET_FRAME_EXTENTS, IntPtr.Zero, new IntPtr (16), false,
}
public IntPtr WINDOW_TYPE {
- get { return window_type.Length > 0 ? window_type[0] : IntPtr.Zero; }
+ get {
+ if (refetch_window_type) {
+ window_type = GetAtomListProperty (display.Atoms._NET_WM_WINDOW_TYPE);
+ refetch_window_type = false;
+ }
+
+ return window_type.Length > 0 ? window_type[0] : IntPtr.Zero;
+ }
set {
Set_WINDOW_TYPE (new IntPtr[] {value}, 1);
}
public void Set_WINDOW_TYPE (IntPtr[] value, int count)
{
+ if (refetch_window_type) {
+ window_type = GetAtomListProperty (display.Atoms._NET_WM_WINDOW_TYPE);
+ refetch_window_type = false;
+ }
+
if (ArrayDifferent (window_type, value)) {
window_type = value;
Xlib.XChangeProperty (display.Handle, WholeWindow,
}
}
- internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key)
+ internal override double GetWindowTransparency (IntPtr handle)
+ {
+ X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
+
+ if (hwnd != null)
+ return hwnd.GetWindowTransparency ();
+ else
+ return 0.0;
+ }
+
+ internal override void SetWindowTransparency (IntPtr handle, double transparency, Color key)
{
X11Hwnd hwnd = (X11Hwnd)Hwnd.ObjectFromHandle(handle);
return (object) ThreadQueue(thread);
}
- internal override bool SupportsTransparency()
+ internal override TransparencySupport SupportsTransparency()
{
return display.SupportsTransparency ();
}
+2006-11-29 Chris Toshok <toshok@ximian.com>
+
+ [ totally cosmetic eye-candy feature, fixes bug #80089 ]
+
+ * Form.cs: only call the XplatUI transparency method (get/set) if
+ SupportsTransparency says it's supported. Otherwise fallback to
+ doing nothing (in the set case) or returning the instance field we
+ cache (in the get case).
+
+ * XplatUIStructs.cs: add TransparencySupport flag enum.
+
+ * XplatUIDriver.cs: add abstract GetWindowTransparency, and track
+ change to SupportsTransparency.
+
+ * XplatUIOSX.cs: stub out GetWindowTransparency, and return
+ TransparencySupport.None from SupportsTransparency.
+
+ * XplatUIX11.cs: Stub out GetWindowTransparency, and return
+ TransparencySupport.Set from SupportsTransparency.
+
+ * XplatUIWin32.cs: implement GetWindowTransparency calling
+ GetLayeredWindowAttributes, and implement SupportsTransparency by
+ checking whether or not both
+ GetWindowTransparency/SetWindowTransparency are available
+ entrypoints. We need to do this since SetWindowTransparency is
+ available as of win2k, but GetWindowTransparency requires winxp.
+ yay win32 api.
+
+ * XplatUI.cs: Add GetWindowTransparency, and change
+ SupportsTransparency to allow for either/both Get/Set.
+
2006-11-29 Chris Toshok <toshok@ximian.com>
* DataGrid.cs: keep from going into an infinite loop redrawing a
return;
}
- if (XplatUI.SupportsTransparency()) {
+ if ((XplatUI.SupportsTransparency() & TransparencySupport.Set) != 0) {
allow_transparency = value;
if (value) {
[MWFCategory("Window Style")]
public double Opacity {
get {
+ if (IsHandleCreated) {
+ if ((XplatUI.SupportsTransparency () & TransparencySupport.Get) != 0)
+ return XplatUI.GetWindowTransparency (Handle);
+ }
+
return opacity;
}
if (IsHandleCreated) {
UpdateStyles();
- XplatUI.SetWindowTransparency(Handle, opacity, TransparencyKey);
+ if ((XplatUI.SupportsTransparency () & TransparencySupport.Set) != 0)
+ XplatUI.SetWindowTransparency(Handle, opacity, TransparencyKey);
}
}
}
UpdateBounds();
- if (XplatUI.SupportsTransparency()) {
+ if ((XplatUI.SupportsTransparency() & TransparencySupport.Set) != 0) {
if (allow_transparency) {
XplatUI.SetWindowTransparency(Handle, Opacity, TransparencyKey);
}
driver.SetWindowStyle(handle, cp);
}
+ internal static double GetWindowTransparency (IntPtr handle)
+ {
+ #if DriverDebug
+ Console.WriteLine("SetWindowTransparency({0}): Called", Window(handle));
+ #endif
+ return driver.GetWindowTransparency(handle);
+ }
+
internal static void SetWindowTransparency(IntPtr handle, double transparency, Color key)
{
#if DriverDebug
return driver.StartLoop(thread);
}
- internal static bool SupportsTransparency() {
+ internal static TransparencySupport SupportsTransparency() {
#if DriverDebug
Console.WriteLine("SupportsTransparency(): Called, result={0}", driver.SupportsTransparency());
#endif
internal abstract void SetWindowStyle(IntPtr handle, CreateParams cp);
+ internal abstract double GetWindowTransparency(IntPtr handle);
internal abstract void SetWindowTransparency(IntPtr handle, double transparency, Color key);
- internal abstract bool SupportsTransparency();
+ internal abstract TransparencySupport SupportsTransparency();
internal virtual void SetAllowDrop (IntPtr handle, bool value)
{
internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key) {
}
- internal override bool SupportsTransparency() {
- return false;
+ internal override double GetWindowTransparency(IntPtr handle)
+ {
+ return 1.0;
+ }
+
+ internal override TransparencySupport SupportsTransparency() {
+ return TransparencySupport.None;
}
internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool Top, bool Bottom) {
internal object refobject;
}
+ [Flags]
+ internal enum TransparencySupport {
+ None = 0x00,
+ Get = 0x01,
+ Set = 0x02,
+ GetSet = 0x03
+ }
+
internal enum WindowActiveFlags {
WA_INACTIVE = 0,
WA_ACTIVE = 1,
Win32SetWindowLong(handle, WindowLong.GWL_EXSTYLE, (uint)cp.ExStyle);
}
-
+ internal override double GetWindowTransparency(IntPtr handle)
+ {
+ LayeredWindowAttributes lwa;
+ COLORREF clrRef;
+ byte alpha;
+
+ Win32GetLayeredWindowAttributes (handle, out clrRef, out alpha, out lwa);
+
+ return ((double)alpha) / 255.0;
+ }
+
internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key) {
LayeredWindowAttributes lwa = LayeredWindowAttributes.LWA_ALPHA;
byte opacity = (byte)(transparency*255);
Win32SetLayeredWindowAttributes(handle, clrRef, opacity, lwa);
}
- internal override bool SupportsTransparency() {
- // We might check with the OS, but I think we're only >=W2k
- return true;
+ TransparencySupport support;
+ bool queried_transparency_support;
+ internal override TransparencySupport SupportsTransparency() {
+ if (queried_transparency_support)
+ return support;
+
+ bool flag;
+ support = TransparencySupport.None;
+
+ flag = true;
+ try {
+ Win32SetLayeredWindowAttributes (IntPtr.Zero, new COLORREF (), 255, LayeredWindowAttributes.LWA_ALPHA);
+ }
+ catch (EntryPointNotFoundException) { flag = false; }
+ catch { /* swallow everything else */ }
+
+ if (flag) support |= TransparencySupport.Set;
+
+ flag = true;
+ try {
+ LayeredWindowAttributes lwa;
+ COLORREF clrRef;
+ byte alpha;
+
+ Win32GetLayeredWindowAttributes (IntPtr.Zero, out clrRef, out alpha, out lwa);
+ }
+ catch (EntryPointNotFoundException) { flag = false; }
+ catch { /* swallow everything else */ }
+
+ if (flag) support |= TransparencySupport.Get;
+
+ queried_transparency_support = true;
+ return support;
}
internal override void UpdateWindow(IntPtr handle) {
[DllImport ("user32.dll", EntryPoint="SetLayeredWindowAttributes", CallingConvention=CallingConvention.StdCall)]
private extern static uint Win32SetLayeredWindowAttributes (IntPtr hwnd, COLORREF crKey, byte bAlpha, LayeredWindowAttributes dwFlags);
+ [DllImport ("user32.dll", EntryPoint="GetLayeredWindowAttributes", CallingConvention=CallingConvention.StdCall)]
+ private extern static uint Win32GetLayeredWindowAttributes (IntPtr hwnd, out COLORREF pcrKey, out byte pbAlpha, out LayeredWindowAttributes pwdFlags);
+
[DllImport ("gdi32.dll", EntryPoint="DeleteObject", CallingConvention=CallingConvention.StdCall)]
private extern static bool Win32DeleteObject(IntPtr o);
SetWMStyles(hwnd, cp);
}
+ internal override double GetWindowTransparency(IntPtr handle)
+ {
+ return 1.0;
+ }
+
internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key) {
Hwnd hwnd;
IntPtr opacity;
return (Object) ThreadQueue(thread);
}
- internal override bool SupportsTransparency() {
+ internal override TransparencySupport SupportsTransparency() {
// We need to check if the x compositing manager is running
- return true;
+ return TransparencySupport.Set;
}
internal override bool SystrayAdd(IntPtr handle, string tip, Icon icon, out ToolTip tt) {