~ubuntu-branches/ubuntu/natty/monodevelop/natty

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Components/MonoDevelop.Components/WindowTransparencyDecorator.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2010-07-05 13:00:05 UTC
  • mfrom: (1.2.8 upstream) (1.3.9 experimental)
  • Revision ID: james.westby@ubuntu.com-20100705130005-d6hp4k5gcn1xkj8c
Tags: 2.4+dfsg-1ubuntu1
* debian/patches/remove_support_for_moonlight.patch,
  debian/patches/dont_add_moonlight_to_core_addins.patch,
  debian/control:
  + Enable support for Moonlight
* debian/rules:
  + Ensure Moonlight addin isn't shipped in main MonoDevelop package by
    mistake

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// 
2
 
// WindowTransparencyDecorator.cs
3
 
// 
4
 
// Author:
5
 
//   Michael Hutchinson <mhutchinson@novell.com>
6
 
//
7
 
// Based on code derived from Banshee.Widgets.EllipsizeLabel
8
 
// by Aaron Bockover (aaron@aaronbock.net)
9
 
// 
10
 
// Copyright (C) 2005-2008 Novell, Inc (http://www.novell.com)
11
 
// 
12
 
// Permission is hereby granted, free of charge, to any person obtaining
13
 
// a copy of this software and associated documentation files (the
14
 
// "Software"), to deal in the Software without restriction, including
15
 
// without limitation the rights to use, copy, modify, merge, publish,
16
 
// distribute, sublicense, and/or sell copies of the Software, and to
17
 
// permit persons to whom the Software is furnished to do so, subject to
18
 
// the following conditions:
19
 
// 
20
 
// The above copyright notice and this permission notice shall be
21
 
// included in all copies or substantial portions of the Software.
22
 
// 
23
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
 
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
 
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26
 
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27
 
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28
 
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29
 
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
 
//
31
 
 
32
 
using System;
33
 
using System.Reflection;
34
 
using System.Runtime.InteropServices;
35
 
 
36
 
namespace MonoDevelop.Components
37
 
{
38
 
        public class WindowTransparencyDecorator
39
 
        {
40
 
                Gtk.Window window;
41
 
                bool semiTransparent;
42
 
                bool snooperInstalled;
43
 
                uint snooperID;
44
 
                const double opacity = 0.2;
45
 
                Delegate snoopFunc;
46
 
                
47
 
                WindowTransparencyDecorator (Gtk.Window window)
48
 
                {
49
 
                        this.window = window;
50
 
                        //HACK: Workaround for GTK# crasher bug where GC collects internal wrapper delegates
51
 
                        snoopFunc = TryBindGtkInternals (this);
52
 
                        
53
 
                        if (snoopFunc != null) {
54
 
                                window.Shown += ShownHandler;
55
 
                                window.Hidden += HiddenHandler;
56
 
                                window.Destroyed += DestroyedHandler;
57
 
                        } else {
58
 
                                snoopFunc = null;
59
 
                                window = null;
60
 
                        }
61
 
                }
62
 
                
63
 
                public static WindowTransparencyDecorator Attach (Gtk.Window window)
64
 
                {
65
 
                        return new WindowTransparencyDecorator (window);
66
 
                }
67
 
                
68
 
                public void Detach ()
69
 
                {
70
 
                        if (window == null)
71
 
                        return;
72
 
                        
73
 
                        //remove the snooper
74
 
                        HiddenHandler (null,  null);
75
 
                        
76
 
                        //annul allreferences between this and the window
77
 
                        window.Shown -= ShownHandler;
78
 
                        window.Hidden -= HiddenHandler;
79
 
                        window.Destroyed -= DestroyedHandler;
80
 
                        snoopFunc = null;
81
 
                        window = null;
82
 
                }
83
 
                
84
 
                void ShownHandler (object sender, EventArgs args)
85
 
                {
86
 
                        if (!snooperInstalled)
87
 
                                snooperID = InstallSnooper (snoopFunc);
88
 
                        snooperInstalled = true;
89
 
                        
90
 
                        //NOTE: we unset transparency when showing, instead of when hiding
91
 
                        //because the latter case triggers a metacity+compositing bug that shows the window again
92
 
                        SemiTransparent = false;
93
 
                }
94
 
                
95
 
                void HiddenHandler (object sender, EventArgs args)
96
 
                {
97
 
                        if (snooperInstalled)
98
 
                                RemoveSnooper (snooperID);
99
 
                        snooperInstalled = false;
100
 
                }
101
 
                
102
 
                void DestroyedHandler (object sender, EventArgs args)
103
 
                {
104
 
                        Detach ();
105
 
                }
106
 
                
107
 
                #pragma warning disable 0169
108
 
                
109
 
                int TransparencyKeySnooper (IntPtr widget, IntPtr rawEvnt, IntPtr data)
110
 
                {
111
 
                        if (rawEvnt != IntPtr.Zero) {
112
 
                                Gdk.EventKey evnt = new Gdk.EventKey (rawEvnt);
113
 
                                if (evnt != null && evnt.Key == Gdk.Key.Control_L || evnt.Key == Gdk.Key.Control_R)
114
 
                                        SemiTransparent = (evnt.Type == Gdk.EventType.KeyPress);
115
 
                        }
116
 
                        return 0; //gboolean FALSE
117
 
                }
118
 
                
119
 
                #pragma warning restore 0169
120
 
                
121
 
                bool SemiTransparent {
122
 
                        set {
123
 
                                if (semiTransparent != value) {
124
 
                                        semiTransparent = value;
125
 
                                        window.Opacity = semiTransparent? opacity : 1.0;
126
 
                                }
127
 
                        }
128
 
                }
129
 
                
130
 
                #region Workaround for GTK# crasher bug where GC collects internal wrapper delegates
131
 
                
132
 
                static WindowTransparencyDecorator ()
133
 
                {
134
 
                        snooper_install = typeof (Gtk.Key).GetMethod ("gtk_key_snooper_install", BindingFlags.NonPublic | BindingFlags.Static);
135
 
                        snooper_remove = typeof (Gtk.Key).GetMethod ("gtk_key_snooper_remove", BindingFlags.NonPublic | BindingFlags.Static);
136
 
                }
137
 
                
138
 
                static MethodInfo snooper_install;
139
 
                static MethodInfo snooper_remove;
140
 
                
141
 
                delegate int GtkKeySnoopFunc (IntPtr widget, IntPtr rawEvnt, IntPtr func_data);
142
 
                
143
 
                static uint InstallSnooper (Delegate del)
144
 
                {
145
 
                        return (uint) snooper_install.Invoke (null, new object[] { del, IntPtr.Zero} );
146
 
                }
147
 
                
148
 
                static void RemoveSnooper (uint id)
149
 
                {
150
 
                        snooper_remove.Invoke (null, new object[] { id });
151
 
                }
152
 
                
153
 
                static bool internalBindingWorks = true;
154
 
                static bool internalBindingTried = false;
155
 
                
156
 
                static Delegate TryBindGtkInternals (WindowTransparencyDecorator instance)
157
 
                {
158
 
                        if (internalBindingTried) {
159
 
                                if (!internalBindingWorks)
160
 
                                        return null;
161
 
                        } else {
162
 
                                internalBindingTried = true;
163
 
                        }
164
 
                        
165
 
                        try {
166
 
                                Type delType = typeof(Gtk.Widget).Assembly.GetType ("GtkSharp.KeySnoopFuncNative");
167
 
                                System.Reflection.MethodInfo met = typeof (WindowTransparencyDecorator).GetMethod ("TransparencyKeySnooper", 
168
 
                                    System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
169
 
                                Delegate ret = Delegate.CreateDelegate (delType, instance, met);
170
 
                                if (ret != null)
171
 
                                        return ret;
172
 
                        } catch {}
173
 
                        
174
 
                        internalBindingWorks = false;
175
 
                        MonoDevelop.Core.LoggingService.LogWarning ("GTK# API has changed, and control-transparency will not be available for popups");
176
 
                        return null;
177
 
                }
178
 
                
179
 
                #endregion
180
 
        }
181
 
}