~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to src/core/Mono.Texteditor/Mono.TextEditor.PopupWindow/TooltipWindow.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
134
134
                                
135
135
                                Gdk.Rectangle geometry = Screen.GetUsableMonitorGeometry (Screen.GetMonitorAtPoint (x, y));
136
136
                                if (nudgeHorizontal) {
137
 
                                        if (allocation.Width <= geometry.Width && x + allocation.Width >= geometry.Width - edgeGap)
138
 
                                                x = geometry.Left + (geometry.Width - allocation.Height - edgeGap);
139
 
                                        if (x <= geometry.Left)
140
 
                                                x = geometry.Left;
 
137
                                        if (allocation.Width <= geometry.Width && x + allocation.Width >= geometry.Left + geometry.Width - edgeGap)
 
138
                                                x = geometry.Left + (geometry.Width - allocation.Width - edgeGap);
 
139
                                        if (x <= geometry.Left + edgeGap)
 
140
                                                x = geometry.Left + edgeGap;
141
141
                                }
142
142
                                
143
143
                                if (nudgeVertical) {
144
 
                                        if (allocation.Height <= geometry.Height && y + allocation.Height >= geometry.Height - edgeGap)
 
144
                                        if (allocation.Height <= geometry.Height && y + allocation.Height >= geometry.Top + geometry.Height - edgeGap)
145
145
                                                y = geometry.Top + (geometry.Height - allocation.Height - edgeGap);
146
 
                                        if (y <= geometry.Top)
147
 
                                                y = geometry.Top;
 
146
                                        if (y <= geometry.Top + edgeGap)
 
147
                                                y = geometry.Top + edgeGap;
148
148
                                }
149
149
                                
150
150
                                if (y != oldY || x != oldX)
442
442
                                QueueResize ();
443
443
                        }
444
444
                }
445
 
                
446
 
                public class WindowTransparencyDecorator
447
 
        {
448
 
                Gtk.Window window;
449
 
                bool semiTransparent;
450
 
                bool snooperInstalled;
451
 
                uint snooperID;
452
 
                const double opacity = 0.2;
453
 
                Delegate snoopFunc;
454
 
                
455
 
                WindowTransparencyDecorator (Gtk.Window window)
456
 
                {
457
 
                        this.window = window;
458
 
                        //HACK: Workaround for GTK# crasher bug where GC collects internal wrapper delegates
459
 
                        snoopFunc = TryBindGtkInternals (this);
460
 
                        
461
 
                        if (snoopFunc != null) {
462
 
                                window.Shown += ShownHandler;
463
 
                                window.Hidden += HiddenHandler;
464
 
                                window.Destroyed += DestroyedHandler;
465
 
                        } else {
466
 
                                snoopFunc = null;
467
 
                                window = null;
468
 
                        }
469
 
                }
470
 
                
471
 
                public static WindowTransparencyDecorator Attach (Gtk.Window window)
472
 
                {
473
 
                        return new WindowTransparencyDecorator (window);
474
 
                }
475
 
                
476
 
                public void Detach ()
477
 
                {
478
 
                        if (window == null)
479
 
                        return;
480
 
                        
481
 
                        //remove the snooper
482
 
                        HiddenHandler (null,  null);
483
 
                        
484
 
                        //annul allreferences between this and the window
485
 
                        window.Shown -= ShownHandler;
486
 
                        window.Hidden -= HiddenHandler;
487
 
                        window.Destroyed -= DestroyedHandler;
488
 
                        snoopFunc = null;
489
 
                        window = null;
490
 
                }
491
 
                
492
 
                void ShownHandler (object sender, EventArgs args)
493
 
                {
494
 
                        if (!snooperInstalled)
495
 
                                snooperID = InstallSnooper (snoopFunc);
496
 
                        snooperInstalled = true;
497
 
                        
498
 
                        //NOTE: we unset transparency when showing, instead of when hiding
499
 
                        //because the latter case triggers a metacity+compositing bug that shows the window again
500
 
                        SemiTransparent = false;
501
 
                }
502
 
                
503
 
                void HiddenHandler (object sender, EventArgs args)
504
 
                {
505
 
                        if (snooperInstalled)
506
 
                                RemoveSnooper (snooperID);
507
 
                        snooperInstalled = false;
508
 
                }
509
 
                
510
 
                void DestroyedHandler (object sender, EventArgs args)
511
 
                {
512
 
                        Detach ();
513
 
                }
514
 
                
515
 
                #pragma warning disable 0169
516
 
                
517
 
                int TransparencyKeySnooper (IntPtr widget, IntPtr rawEvnt, IntPtr data)
518
 
                {
519
 
                        if (rawEvnt != IntPtr.Zero) {
520
 
                                Gdk.EventKey evnt = new Gdk.EventKey (rawEvnt);
521
 
                                if (evnt != null && evnt.Key == Gdk.Key.Control_L || evnt.Key == Gdk.Key.Control_R)
522
 
                                        SemiTransparent = (evnt.Type == Gdk.EventType.KeyPress);
523
 
                        }
524
 
                        return 0; //gboolean FALSE
525
 
                }
526
 
                
527
 
                #pragma warning restore 0169
528
 
                
529
 
                bool SemiTransparent {
530
 
                        set {
531
 
                                if (semiTransparent != value) {
532
 
                                        semiTransparent = value;
533
 
                                        window.Opacity = semiTransparent? opacity : 1.0;
534
 
                                }
535
 
                        }
536
 
                }
537
 
                
538
 
                #region Workaround for GTK# crasher bug where GC collects internal wrapper delegates
539
 
                
540
 
                static WindowTransparencyDecorator ()
541
 
                {
542
 
                        snooper_install = typeof (Gtk.Key).GetMethod ("gtk_key_snooper_install", BindingFlags.NonPublic | BindingFlags.Static);
543
 
                        snooper_remove = typeof (Gtk.Key).GetMethod ("gtk_key_snooper_remove", BindingFlags.NonPublic | BindingFlags.Static);
544
 
                }
545
 
                
546
 
                static MethodInfo snooper_install;
547
 
                static MethodInfo snooper_remove;
548
 
                
549
 
                delegate int GtkKeySnoopFunc (IntPtr widget, IntPtr rawEvnt, IntPtr func_data);
550
 
                
551
 
                static uint InstallSnooper (Delegate del)
552
 
                {
553
 
                        return (uint) snooper_install.Invoke (null, new object[] { del, IntPtr.Zero} );
554
 
                }
555
 
                
556
 
                static void RemoveSnooper (uint id)
557
 
                {
558
 
                        snooper_remove.Invoke (null, new object[] { id });
559
 
                }
560
 
                
561
 
                static bool internalBindingWorks = true;
562
 
                static bool internalBindingTried = false;
563
 
                
564
 
                static Delegate TryBindGtkInternals (WindowTransparencyDecorator instance)
565
 
                {
566
 
                        if (internalBindingTried) {
567
 
                                if (!internalBindingWorks)
568
 
                                        return null;
569
 
                        } else {
570
 
                                internalBindingTried = true;
571
 
                        }
572
 
                        
573
 
                        try {
574
 
                                Type delType = typeof(Gtk.Widget).Assembly.GetType ("GtkSharp.KeySnoopFuncNative");
575
 
                                System.Reflection.MethodInfo met = typeof (WindowTransparencyDecorator).GetMethod ("TransparencyKeySnooper", 
576
 
                                    System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
577
 
                                Delegate ret = Delegate.CreateDelegate (delType, instance, met);
578
 
                                if (ret != null)
579
 
                                        return ret;
580
 
                        } catch {}
581
 
                        
582
 
                        internalBindingWorks = false;
583
 
                        Console.WriteLine ("GTK# API has changed, and control-transparency will not be available for popups");
584
 
                        return null;
585
 
                }
586
 
                
587
 
                #endregion
588
 
        }
589
445
        }
590
446
}