~cszikszoy/do/do-fix-keybindings

« back to all changes in this revision

Viewing changes to Do.Interface.Linux.Docky/src/Docky.Interface/DockArea.cs

  • Committer: Chris S.
  • Date: 2009-06-18 06:18:12 UTC
  • mfrom: (1107.2.124 trunk)
  • Revision ID: chris@szikszoy.com-20090618061812-8ynmedlxpmvwkwe9
merge trunk & make properties public

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
using Gtk;
27
27
 
28
28
using Do.Platform;
 
29
using Do.Interface.Wink;
29
30
using Do.Interface.Xlib;
30
31
 
31
32
using Docky.Core;
41
42
        {
42
43
                public static readonly TimeSpan BaseAnimationTime = new TimeSpan (0, 0, 0, 0, 150);
43
44
                
 
45
                static DateTime UpdateTimeStamp (DateTime lastStamp, TimeSpan animationLength)
 
46
                {
 
47
                        TimeSpan delta = DateTime.UtcNow - lastStamp;
 
48
                        if (delta < animationLength)
 
49
                                return DateTime.UtcNow.Subtract (animationLength - delta);
 
50
                        return DateTime.UtcNow;
 
51
                }
 
52
                
44
53
                const uint OffDockWakeupTime = 250;
45
54
                const uint OnDockWakeupTime = 20;
46
 
                const int UrgentBounceHeight = 100;
 
55
                
 
56
                const int UrgentBounceHeight = 80;
47
57
                const int LaunchBounceHeight = 30;
48
58
 
49
59
                TimeSpan BounceTime = new TimeSpan (0, 0, 0, 0, 700);
50
60
                TimeSpan InsertAnimationTime = new TimeSpan (0, 0, 0, 0, 150*5);
51
61
                
52
62
                #region Private Variables
53
 
                Gdk.Point cursor;
54
 
                
55
63
                DateTime enter_time = new DateTime (0);
56
64
                DateTime interface_change_time = new DateTime (0);
57
65
                DateTime last_draw_timeout = new DateTime (0);
58
 
                DateTime cursor_update = new DateTime (0);
 
66
                DateTime showhide_time = new DateTime (0);
 
67
                DateTime painter_time = new DateTime (0);
59
68
                
60
 
                bool disposed;
 
69
                TimeSpan painter_span;
61
70
                
62
71
                uint animation_timer;
63
 
                uint cursor_timer;
64
72
                
65
73
                DockWindow window;
66
74
                
 
75
                DrawingService drawing_service;
 
76
                
67
77
                #endregion
68
78
                
69
79
                #region Public Properties
 
80
                //// <value>
 
81
                /// Returns true if the cursor is over the visible part of the dock or the pixel closest to its autohide edge
 
82
                /// </value>
 
83
                public bool CursorIsOverDockArea { get; private set; }
70
84
                
71
85
                /// <value>
72
86
                /// The width of the docks window, but not the visible dock
78
92
                /// </value>
79
93
                public int Height { get; private set; }
80
94
                
 
95
                //// <value>
 
96
                /// Returns true if the dock is currently being overlayed by an IDockPainter
 
97
                /// </value>
 
98
                public bool PainterOverlayVisible { get; private set; }
 
99
                
81
100
                /// <value>
82
101
                /// The width of the visible dock
83
102
                /// </value>
91
110
                public int DockHeight {
92
111
                        get { return PositionProvider.DockHeight; }
93
112
                }
94
 
 
 
113
                
95
114
                public uint[] StrutRequest {
96
115
                        get {
97
116
                                uint[] values = new uint[12];
98
 
                                Gdk.Rectangle geo = LayoutUtils.MonitorGemonetry ();
 
117
                                Gdk.Rectangle geo = LayoutUtils.MonitorGeometry ();
99
118
                                
100
 
                                if (DockPreferences.AutoHide || DockPreferences.AllowOverlap)
 
119
                                if (DockPreferences.AutohideType != AutohideType.None)
101
120
                                        return values;
102
121
                                
103
122
                                switch (DockPreferences.Orientation) {
116
135
                        }
117
136
                }
118
137
 
 
138
                /// <value>
 
139
                /// The current cursor as known to the dock.
 
140
                /// </value>
 
141
                public Gdk.Point Cursor {
 
142
                        get {
 
143
                                return CursorTracker.Cursor;
 
144
                        }
 
145
                }
 
146
                
 
147
                public Gdk.Rectangle MinimumDockArea {
 
148
                        get {
 
149
                                return PositionProvider.MinimumDockArea;
 
150
                        }
 
151
                }
119
152
                #endregion
120
153
                
 
154
                AutohideTracker AutohideTracker { get; set; }
 
155
                
 
156
                CursorTracker CursorTracker { get; set; }
 
157
                
 
158
                DnDTracker DnDTracker { get; set; }
 
159
                
121
160
                DockAnimationState AnimationState { get; set; }
122
161
                
123
162
                ItemPositionProvider PositionProvider { get; set; }
124
163
 
125
164
                new DockItemMenu PopupMenu { get; set; }
126
165
                
127
 
                bool CursorIsOverDockArea {     get; set; }
128
 
 
129
 
                ModifierType CursorModifier { get; set; }
130
 
                
131
166
                ReadOnlyCollection<AbstractDockItem> DockItems { 
132
167
                        get { return DockServices.ItemsService.DockItems; } 
133
168
                }
134
169
                
135
170
                AbstractDockItem CurrentDockItem {
136
171
                        get {
137
 
                                try { return DockItems [PositionProvider.IndexAtPosition (Cursor)]; }
138
 
                                catch { return null; }
 
172
                                int index = PositionProvider.IndexAtPosition (Cursor);
 
173
                                if (index >= 0 && index < DockItems.Count)
 
174
                                        return DockItems [index];
 
175
                                return null;
139
176
                        }
140
177
                }
141
178
                
143
180
                        get { return DockPreferences.SummonTime; }
144
181
                }
145
182
                
146
 
                /// <value>
147
 
                /// The current cursor as known to the dock.
148
 
                /// </value>
149
 
                public Gdk.Point Cursor {
 
183
                bool WindowIntersectingOther { 
 
184
                        get { return AutohideTracker.WindowIntersectingOther; }
 
185
                }
 
186
                
 
187
                IEnumerable<Gdk.Window> WindowStack {
150
188
                        get {
151
 
                                return cursor;
152
 
                        }
153
 
                        set {
154
 
                                bool cursorIsOverDockArea = CursorIsOverDockArea;
155
 
                                cursor = value;
156
 
 
157
 
                                // We set this value here instead of dynamically checking due to performance constraints.
158
 
                                // Ideally our CursorIsOverDockArea getter would do this fairly simple calculation, but it gets
159
 
                                // called about 20 to 30 times per render loop, so the savings do add up.
160
 
                                Gdk.Rectangle dockRegion;
161
 
                                if (PainterOverlayVisible)
162
 
                                        dockRegion = GetDockArea ();
163
 
                                else
164
 
                                        dockRegion = MinimumDockArea;
165
 
                                
166
 
                                if (cursorIsOverDockArea) {
167
 
                                        dockRegion.Inflate (0, (int) (IconSize * (DockPreferences.ZoomPercent - 1)) + 22);
168
 
                                        CursorIsOverDockArea = dockRegion.Contains (cursor);
169
 
                                } else {
170
 
                                        if (DockPreferences.AutoHide) {
171
 
                                                switch (DockPreferences.Orientation) {
172
 
                                                case DockOrientation.Bottom:
173
 
                                                        dockRegion.Y += dockRegion.Height - 1;
174
 
                                                        dockRegion.Height = 1;
175
 
                                                        break;
176
 
                                                case DockOrientation.Top:
177
 
                                                        dockRegion.Height = 1;
178
 
                                                        break;
179
 
                                                }
 
189
                                try {
 
190
                                        return Screen.WindowStack;
 
191
                                } catch { 
 
192
                                        try {
 
193
                                                return Wnck.Screen.Default.WindowsStacked.Select (wnk => Gdk.Window.ForeignNew ((uint) wnk.Xid));
 
194
                                        } catch {
 
195
                                                return null;
180
196
                                        }
181
 
                                        
182
 
                                        CursorIsOverDockArea = dockRegion.Contains (cursor);
183
 
                                }
184
 
                                
185
 
                                // When we change over this boundry, it will normally trigger an animation, we need to be sure to catch it
186
 
                                if (CursorIsOverDockArea != cursorIsOverDockArea) {
187
 
                                        ResetCursorTimer ();
188
 
                                        enter_time = DateTime.UtcNow;
189
 
                                        AnimatedDraw ();
190
 
                                }
191
 
 
192
 
                                DragCursorUpdate ();
193
 
                        }
194
 
                }
195
 
                
196
 
                Gdk.Rectangle MinimumDockArea {
197
 
                        get {
198
 
                                return PositionProvider.MinimumDockArea;
 
197
                                }
199
198
                        }
200
199
                }
201
200
                
202
201
                public DockArea (DockWindow window) : base ()
203
202
                {
 
203
                        drawing_service = new DrawingService (this);
 
204
                        DockServices.RegisterService (drawing_service);
 
205
                        
204
206
                        this.window = window;
205
207
                        
 
208
                        ScreenUtils.Initialize ();
 
209
                        WindowUtils.Initialize ();
 
210
                        
 
211
                        AnimationState   = new DockAnimationState ();
 
212
                        AutohideTracker  = new AutohideTracker (this);
 
213
                        CursorTracker    = new CursorTracker (window, OffDockWakeupTime);
206
214
                        PositionProvider = new ItemPositionProvider (this);
207
 
                        
208
 
                        SetSize ();
209
 
                        
210
 
                        AnimationState = new DockAnimationState ();
 
215
                        DnDTracker       = new DnDTracker (this, PositionProvider, CursorTracker);
 
216
                        PopupMenu        = new DockItemMenu ();
 
217
                        
211
218
                        BuildAnimationStateEngine ();
212
 
                        
213
 
                        PopupMenu = new DockItemMenu ();
214
 
 
215
 
                        Cursor = new Gdk.Point (-1, -1);
216
219
 
217
220
                        this.SetCompositeColormap ();
218
221
 
219
 
                        // fixme, we should be using the PointerMotionHintMask
220
 
                        AddEvents ((int) EventMask.PointerMotionMask |
221
 
                                   (int) EventMask.EnterNotifyMask |
222
 
                                   (int) EventMask.ButtonPressMask | 
 
222
                        AddEvents ((int) EventMask.ButtonPressMask | 
223
223
                                   (int) EventMask.ButtonReleaseMask |
224
224
                                   (int) EventMask.ScrollMask |
225
225
                                   (int) EventMask.FocusChangeMask);
226
226
                        
 
227
                        SetSize ();
227
228
                        DoubleBuffered = false;
228
229
 
229
230
                        BuildRendering ();
230
 
                        BuildDragAndDrop ();
231
231
                        
232
232
                        RegisterEvents ();
233
 
                        RegisterGtkDragDest ();
234
 
                        RegisterGtkDragSource ();
235
233
                        
236
234
                        ResetCursorTimer ();
237
235
                }
239
237
                void SetSize ()
240
238
                {
241
239
                        Gdk.Rectangle geo;
242
 
                        geo = LayoutUtils.MonitorGemonetry ();
 
240
                        geo = LayoutUtils.MonitorGeometry ();
243
241
                        
244
242
                        Width = geo.Width;
245
 
                        Height = DockPreferences.FullIconSize + PositionProvider.VerticalBuffer + Math.Max (UrgentBounceHeight, LaunchBounceHeight);
 
243
                        Height = DockPreferences.FullIconSize + 2 * PositionProvider.VerticalBuffer + UrgentBounceHeight;
 
244
                        Height = Math.Max (150, Height);
246
245
                        
247
246
                        SetSizeRequest (Width, Height);
248
247
                }
254
253
                        
255
254
                        DockPreferences.MonitorChanged += HandleMonitorChanged; 
256
255
                        DockPreferences.IconSizeChanged += HandleIconSizeChanged; 
 
256
                        DockPreferences.OrientationChanged += HandleOrientationChanged; 
257
257
                        
258
258
                        DockServices.PainterService.PainterShowRequest += HandlePainterShowRequest;
259
259
                        DockServices.PainterService.PainterHideRequest += HandlePainterHideRequest;
268
268
                        Realized += (o, e) => SetParentInputMask ();
269
269
                        Realized += (o, a) => GdkWindow.SetBackPixmap (null, false);
270
270
                        
 
271
                        AutohideTracker.IntersectionChanged += HandleIntersectionChanged;
 
272
                        Wnck.Screen.Default.ActiveWindowChanged += HandleActiveWindowChanged;
 
273
                        
 
274
                        CursorTracker.CursorUpdated += HandleCursorUpdated;
 
275
                        
 
276
                        DnDTracker.DragEnded += HandleDragEnded;
 
277
                        DnDTracker.DrawRequired += HandleDrawRequired; 
 
278
                        
271
279
                        StyleSet += (o, a) => { 
272
280
                                if (IsRealized)
273
281
                                        GdkWindow.SetBackPixmap (null, false);
281
289
                        
282
290
                        DockPreferences.MonitorChanged -= HandleMonitorChanged;
283
291
                        DockPreferences.IconSizeChanged -= HandleIconSizeChanged; 
 
292
                        DockPreferences.OrientationChanged -= HandleOrientationChanged; 
284
293
                        
285
294
                        DockServices.PainterService.PainterShowRequest -= HandlePainterShowRequest;
286
295
                        DockServices.PainterService.PainterHideRequest -= HandlePainterHideRequest;
291
300
                        PopupMenu.Shown -= OnDockItemMenuShown;
292
301
                        
293
302
                        Services.Core.UniverseInitialized -= HandleUniverseInitialized;
 
303
                        
 
304
                        AutohideTracker.IntersectionChanged -= HandleIntersectionChanged;
 
305
                        Wnck.Screen.Default.ActiveWindowChanged -= HandleActiveWindowChanged;
 
306
                        
 
307
                        CursorTracker.CursorUpdated -= HandleCursorUpdated;
 
308
                        
 
309
                        DnDTracker.DragEnded -= HandleDragEnded;
 
310
                        DnDTracker.DrawRequired -= HandleDrawRequired; 
294
311
                }
295
312
                
296
313
                void BuildAnimationStateEngine ()
302
319
                                                     () => (CursorIsOverDockArea && ZoomIn != 1) || (!CursorIsOverDockArea && ZoomIn != 0));
303
320
                        
304
321
                        AnimationState.AddCondition (Animations.Open,
305
 
                                                     () => DateTime.UtcNow - enter_time < SummonTime ||
306
 
                                                     DateTime.UtcNow - interface_change_time < SummonTime);
 
322
                                                     () => DateTime.UtcNow - enter_time < BaseAnimationTime ||
 
323
                                                     DateTime.UtcNow - interface_change_time < BaseAnimationTime);
307
324
                        
308
325
                        AnimationState.AddCondition (Animations.Bounce,
309
326
                                                     () => DockItems.Any (di => di.TimeSinceClick <= BounceTime));
312
329
                                                     () => DockItems.Any (di => DateTime.UtcNow - di.AttentionRequestStartTime < BounceTime));
313
330
                        
314
331
                        AnimationState.AddCondition (Animations.InputModeChanged,
315
 
                                                     () => DateTime.UtcNow - interface_change_time < SummonTime);
 
332
                                                     () => DateTime.UtcNow - interface_change_time < SummonTime || 
 
333
                                                     DateTime.UtcNow - showhide_time < SummonTime);
 
334
                }
 
335
                
 
336
                void HandleCursorUpdated (object sender, CursorUpdatedArgs args)
 
337
                {
 
338
                        if (PopupMenu.Visible)
 
339
                                return;
 
340
                        
 
341
                        UpdateCursorIsOverDockArea ();
 
342
 
 
343
                        bool cursorMoveWarrantsDraw = CursorIsOverDockArea && args.OldCursor.X != args.NewCursor.X;
 
344
 
 
345
                        if (DnDTracker.DragResizing || cursorMoveWarrantsDraw) 
 
346
                                AnimatedDraw ();
 
347
                }
 
348
                
 
349
                void HandleDrawRequired(object sender, EventArgs e)
 
350
                {
 
351
                        AnimatedDraw ();
 
352
                }
 
353
 
 
354
                void HandleDragEnded(object sender, EventArgs e)
 
355
                {
 
356
                        ResetCursorTimer ();
 
357
                        Reconfigure ();
316
358
                }
317
359
 
318
360
                void HandleItemNeedsUpdate (object sender, UpdateRequestArgs args)
319
361
                {
320
362
                        if (args.Type == UpdateRequestType.NeedsAttentionSet) {
321
363
                                SetParentInputMask ();
 
364
                                Reconfigure ();
 
365
                                
 
366
                                GLib.Timeout.Add ((uint) BounceTime.Milliseconds + 20, delegate {
 
367
                                        Reconfigure ();
 
368
                                        return false;
 
369
                                });
 
370
                        }
 
371
                        
 
372
                        if (args.Type == UpdateRequestType.IconChanged || args.Type == UpdateRequestType.NameChanged) {
 
373
                                RequestIconRender (args.Item);
 
374
                        } else {
 
375
                                RequestFullRender ();
322
376
                        }
323
377
                        AnimatedDraw ();
324
378
                }
327
381
                {
328
382
                        Reconfigure ();
329
383
                }
330
 
                
331
 
                void HandleSizeChanged(object sender, EventArgs e)
332
 
                {
333
 
                        Reconfigure ();
334
 
                }
335
 
                
336
 
                void Reconfigure ()
337
 
                {
338
 
                        if (!Visible || !IsRealized || drag_resizing)
 
384
 
 
385
                void HandleOrientationChanged()
 
386
                {
 
387
                        Reconfigure ();
 
388
                        window.Reposition ();
 
389
                }
 
390
                
 
391
                void HandleSizeChanged (object sender, EventArgs e)
 
392
                {
 
393
                        Reconfigure ();
 
394
                }
 
395
                
 
396
                public void Reconfigure ()
 
397
                {
 
398
                        if (!Visible || !IsRealized || DnDTracker.DragResizing)
339
399
                                return;
340
400
                        
341
401
                        SetSize ();
344
404
                        SetParentInputMask ();
345
405
                        SetIconRegions ();
346
406
                        window.DelaySetStruts ();
 
407
                        AnimatedDraw ();
347
408
                }
348
409
                
349
 
                void HandleUniverseInitialized(object sender, EventArgs e)
 
410
                void HandleUniverseInitialized (object sender, EventArgs e)
350
411
                {
351
412
                        GLib.Timeout.Add (2000, delegate {
352
413
                                DockServices.ItemsService.ForceUpdate ();
357
418
                
358
419
                void HandleIconSizeChanged()
359
420
                {
 
421
                        Reconfigure ();
360
422
                        AnimatedDraw ();
361
423
                }
362
424
 
365
427
                        if (sender != Painter && sender != LastPainter) return;
366
428
                        
367
429
                        if (args.Animated) {
368
 
                                if (AnimationState.Contains (Animations.Painter))
369
 
                                        AnimationState.RemoveCondition (Animations.Painter);
370
 
                                TimeSpan span = args.AnimationLength;
371
 
                                
372
 
                                DateTime current_time = DateTime.UtcNow;
373
 
                                AnimationState.AddCondition (Animations.Painter, () => DateTime.UtcNow - current_time < span);
 
430
                                painter_span = args.AnimationLength;
 
431
                                painter_time = DateTime.UtcNow;
 
432
                                if (!AnimationState.Contains (Animations.Painter))
 
433
                                        AnimationState.AddCondition (Animations.Painter, () => DateTime.UtcNow - painter_time < painter_span);
374
434
                        }
375
435
                        AnimatedDraw ();
376
436
                }
383
443
 
384
444
                        Painter = null;
385
445
                        PainterOverlayVisible = false;
386
 
                        interface_change_time = DateTime.UtcNow;
 
446
                        interface_change_time = UpdateTimeStamp (interface_change_time, SummonTime);
387
447
 
388
448
                        SetParentInputMask ();
389
449
                        AnimatedDraw ();
394
454
                        });
395
455
 
396
456
                        window.UnpresentWindow ();
397
 
                        RegisterGtkDragSource ();
 
457
                        DnDTracker.Enable ();
398
458
                }
399
459
 
400
460
                void HandlePainterShowRequest(object sender, EventArgs e)
408
468
                                        Painter.Interrupt ();
409
469
                                Painter = painter;
410
470
                                PainterOverlayVisible = true;
411
 
                                interface_change_time = DateTime.UtcNow;
 
471
                                interface_change_time = UpdateTimeStamp (interface_change_time, SummonTime);
412
472
 
413
473
                                SetParentInputMask ();
414
474
                                AnimatedDraw ();
417
477
                        }
418
478
                        
419
479
                        window.PresentWindow ();
420
 
                        UnregisterGtkDragSource ();
 
480
                        DnDTracker.Disable ();
421
481
                }
422
482
                
423
483
                void ResetCursorTimer ()
424
484
                {
425
 
                        if (disposed)
426
 
                                return;
427
 
                        if (cursor_timer > 0)
428
 
                                GLib.Source.Remove (cursor_timer);
429
 
                        
430
 
                        uint time = (CursorIsOverDockArea || drag_resizing) ? OnDockWakeupTime : OffDockWakeupTime;
431
 
                        cursor_timer = GLib.Timeout.Add (time, OnCursorTimerEllapsed);
 
485
                        CursorTracker.TimerLength = (CursorIsOverDockArea || DnDTracker.DragResizing) ? OnDockWakeupTime : OffDockWakeupTime;
432
486
                }
433
487
                
434
 
                bool OnCursorTimerEllapsed ()
 
488
                void UpdateCursorIsOverDockArea ()
435
489
                {
436
 
                        ManualCursorUpdate ();
437
 
                        
438
 
                        // if we have a painter visible this takes care of interrupting it on mouse off
439
 
                        if (!CursorIsOverDockArea && PainterOverlayVisible && (DateTime.UtcNow - enter_time).TotalMilliseconds > 400)
440
 
                                InterruptPainter ();
441
 
                        
442
 
                        return true;
 
490
                        bool tmp = CursorIsOverDockArea;
 
491
                        
 
492
                        Gdk.Rectangle dockRegion;
 
493
                        if (PainterOverlayVisible)
 
494
                                dockRegion = GetDockArea ();
 
495
                        else
 
496
                                dockRegion = MinimumDockArea;
 
497
                        
 
498
                        if (tmp) {
 
499
                                dockRegion.Inflate (0, (int) (IconSize * (DockPreferences.ZoomPercent - 1)) + 22);
 
500
                        } else {
 
501
                                if (IsHidden) {
 
502
                                        switch (DockPreferences.Orientation) {
 
503
                                        case DockOrientation.Bottom:
 
504
                                                dockRegion.Y += dockRegion.Height - 1;
 
505
                                                dockRegion.Height = 1;
 
506
                                                break;
 
507
                                        case DockOrientation.Top:
 
508
                                                dockRegion.Height = 1;
 
509
                                                break;
 
510
                                        }
 
511
                                }
 
512
                        }
 
513
                        
 
514
                        if (PainterOverlayVisible)
 
515
                                CursorIsOverDockArea = dockRegion.Contains (new Gdk.Point (dockRegion.X, Cursor.Y));
 
516
                        else
 
517
                                CursorIsOverDockArea = dockRegion.Contains (Cursor);
 
518
                        
 
519
                        if (CursorIsOverDockArea != tmp) {
 
520
                                ResetCursorTimer ();
 
521
                                enter_time = UpdateTimeStamp (enter_time, BaseAnimationTime);
 
522
                                
 
523
                                switch (DockPreferences.AutohideType) {
 
524
                                case AutohideType.Autohide:
 
525
                                        showhide_time = enter_time;
 
526
                                        break;
 
527
                                case AutohideType.Intellihide:
 
528
                                        if (WindowIntersectingOther)
 
529
                                                showhide_time = enter_time;
 
530
                                        break;
 
531
                                }
 
532
                                AnimatedDraw ();
 
533
                                
 
534
                                if (PainterOverlayVisible) {
 
535
                                        GLib.Timeout.Add (500, delegate {
 
536
                                                if (!CursorIsOverDockArea && PainterOverlayVisible && (DateTime.UtcNow - enter_time).TotalMilliseconds > 400)
 
537
                                                        InterruptPainter ();
 
538
                                                return false;
 
539
                                        });
 
540
                                }
 
541
                        }
 
542
                        
443
543
                }
444
544
                
445
545
                void AnimatedDraw ()
494
594
                        DockPreferences.MaxIconSize = (int) (((double) Width / MinimumDockArea.Width) * IconSize);
495
595
                        
496
596
                        SetIconRegions ();
 
597
                        RequestFullRender ();
 
598
                        UpdateCursorIsOverDockArea ();
497
599
                        AnimatedDraw ();
498
600
                }
499
601
                
502
604
                        // While an popup menus are being showing, the dock does not recieve mouse updates.  This is
503
605
                        // both a good thing and a bad thing.  We must at the very least update the cursor position once the
504
606
                        // popup is no longer in view.
505
 
                        ManualCursorUpdate ();
 
607
                        CursorTracker.Enabled = true;
506
608
                        AnimatedDraw ();
507
609
                }
508
610
                
511
613
                /// </summary>
512
614
                void OnDockItemMenuShown (object o, EventArgs args)
513
615
                {
 
616
                        CursorTracker.Enabled = false;
514
617
                        AnimatedDraw ();
515
618
                }
516
 
                
517
 
                void ManualCursorUpdate ()
518
 
                {
519
 
                        if ((DateTime.UtcNow - cursor_update).TotalMilliseconds < 15) {
520
 
                                return;
521
 
                        }
522
 
                        
523
 
                        int x, y;
524
 
                        ModifierType mod;
525
 
                        Gdk.Screen screen;
526
 
                        
527
 
                        Display.GetPointer (out screen, out x, out y, out mod);
528
 
                        
529
 
                        if (screen == Screen) {
530
 
                                Gdk.Rectangle geo, hide_offset;
531
 
                                window.GetBufferedPosition (out geo.X, out geo.Y);
532
 
                                window.WindowHideOffset (out hide_offset.X, out hide_offset.Y);
533
 
 
534
 
                                x -= geo.X - hide_offset.X;
535
 
                                y -= geo.Y - hide_offset.Y;
536
 
                        } else {
537
 
                                x = -4000;
538
 
                                y = -4000;
539
 
                        }
540
 
                        
541
 
                        SetupCursor (x, y, mod);
542
 
                }
543
 
                
544
 
                void SetupCursor (int x, int y, ModifierType mod)
545
 
                {
546
 
                        CursorModifier = mod;
547
 
                        
548
 
                        if ((Cursor.X == x && Cursor.Y == y) || PopupMenu.Visible)
549
 
                                return;
550
 
                        
551
 
                        Gdk.Point old_cursor_location = Cursor;
552
 
                        Cursor = new Gdk.Point (x, y);
553
 
 
554
 
                        ConfigureCursor ();
555
 
 
556
 
                        if (drag_resizing)
557
 
                                HandleDragMotion ();
558
 
                        
559
 
                        bool cursorMoveWarrantsDraw = CursorIsOverDockArea && old_cursor_location.X != Cursor.X;
560
 
 
561
 
                        if (drag_resizing || cursorMoveWarrantsDraw) 
562
 
                                AnimatedDraw ();
563
 
                }
564
 
 
565
 
                protected override bool OnMotionNotifyEvent (Gdk.EventMotion evnt)
566
 
                {
567
 
                        GtkDragging = false;
568
 
                        SetupCursor ((int) evnt.X, (int) evnt.Y, evnt.State);
569
 
                        cursor_update = DateTime.UtcNow;
570
 
                        return base.OnMotionNotifyEvent (evnt);
571
 
                }
572
 
                
573
 
                protected override bool OnEnterNotifyEvent (Gdk.EventCrossing evnt)
574
 
                {
575
 
                        ResetCursorTimer ();
576
 
                        ManualCursorUpdate ();
577
 
                        return base.OnEnterNotifyEvent (evnt);
578
 
                }
579
 
 
580
 
                protected override bool OnButtonPressEvent (Gdk.EventButton evnt)
581
 
                {
582
 
                        if (CursorNearDraggableEdge)
583
 
                                StartDrag ();
584
 
                        
585
 
                        return base.OnButtonPressEvent (evnt);
586
 
                }
587
 
                
 
619
 
588
620
                public void ProxyButtonReleaseEvent (Gdk.EventButton evnt)
589
621
                {
590
622
                        HandleButtonReleaseEvent (evnt);
601
633
                private void HandleButtonReleaseEvent (Gdk.EventButton evnt)
602
634
                {
603
635
                        // lets not do anything in this case
604
 
                        if (drag_resizing) {
605
 
                                EndDrag ();
606
 
                                return;
607
 
                        }
 
636
                        if (DnDTracker.DragResizing) return;
608
637
                        
609
638
                        if (PainterOverlayVisible) {
610
639
                                Painter.Clicked (GetDockArea (), Cursor);
637
666
                                }
638
667
                                
639
668
                                //send off the clicks
640
 
                                Gdk.Point relative_point = Gdk.Point.Zero;
 
669
                                PointD relative_point = RelativePointOverItem (item);
641
670
                                DockItems [item].Clicked (evnt.Button, evnt.State, relative_point);
642
671
                                
643
672
                                AnimatedDraw ();
644
673
                        }
645
674
                        return;
646
675
                }
 
676
                
 
677
                PointD RelativePointOverItem (int item)
 
678
                {
 
679
                        PointD relative_point = new PointD (0,0);
 
680
                        double zoom;
 
681
                        PointD center;
 
682
                        IconZoomedPosition (item, out center, out zoom);
 
683
                        
 
684
                        int left = (int) (center.X - DockItems [item].Width * zoom / 2);
 
685
                        int top = (int) (center.Y - DockItems [item].Height * zoom / 2);
 
686
                        int right = (int) (center.X + DockItems [item].Width * zoom / 2);
 
687
                        int bottom = (int) (center.Y + DockItems [item].Height * zoom / 2);
 
688
                        
 
689
                        relative_point.X = (Cursor.X - left) / (double) (right - left);
 
690
                        relative_point.Y = (Cursor.Y - top) / (double) (bottom - top);
 
691
                        
 
692
                        return relative_point;
 
693
                }
647
694
 
648
695
                protected override bool OnScrollEvent (Gdk.EventScroll evnt)
649
696
                {
650
 
                        int item = PositionProvider.IndexAtPosition ((int) evnt.X, (int) evnt.Y);
651
 
                        if (item == -1)
652
 
                                return false;
653
 
                        
654
 
                        DockItems [item].Scrolled (evnt.Direction);
 
697
                        if (PainterOverlayVisible) {
 
698
                                Painter.Scrolled (evnt.Direction);
 
699
                        } else {
 
700
                                int item = PositionProvider.IndexAtPosition ((int) evnt.X, (int) evnt.Y);
 
701
                                if (item >= 0 && item < DockItems.Count)
 
702
                                        DockItems [item].Scrolled (evnt.Direction);
 
703
                        }
655
704
                        return base.OnScrollEvent (evnt);
656
705
                }
657
706
                
658
707
                void SetIconRegions ()
659
708
                {
660
 
                        Gdk.Rectangle pos, area, offset;
 
709
                        Gdk.Rectangle pos, area;
661
710
                        window.GetPosition (out pos.X, out pos.Y);
662
711
                        window.GetSize (out pos.Width, out pos.Height);
663
712
                        
664
 
                        window.WindowHideOffset (out offset.X, out offset.Y);
665
713
                        // we use geo here instead of our position for the Y value because we know the parent window
666
714
                        // may offset us when hidden. This is not desired...
667
715
                        for (int i = 0; i < DockItems.Count; i++) {
668
716
                                Gdk.Point position = PositionProvider.IconUnzoomedPosition (i);
669
 
                                area = new Gdk.Rectangle (pos.X + (position.X - IconSize / 2) - offset.X,
670
 
                                                          pos.Y + (position.Y - IconSize / 2) - offset.Y,
 
717
                                area = new Gdk.Rectangle (pos.X + (position.X - IconSize / 2),
 
718
                                                          pos.Y + (position.Y - IconSize / 2),
671
719
                                                          IconSize,
672
720
                                                          IconSize);
673
721
                                DockItems [i].SetIconRegion (area);
686
734
                                offset = GetDockArea ().Height;
687
735
                                offset = offset * 2 + 10;
688
736
                        } else {
689
 
                                if (DockPreferences.AutoHide && !drag_resizing) {
690
 
                                        // setting the offset to 2 will trigger the parent window to unhide us if we are hidden.
691
 
                                        if (AnimationState [Animations.UrgencyChanged])
692
 
                                                offset = 2;
693
 
                                        else
694
 
                                                offset = 1;
 
737
                                if (IsHidden && !DnDTracker.DragResizing) {
 
738
                                        offset = 1;
695
739
                                } else {
696
740
                                        offset = GetDockArea ().Height;
697
741
                                }
698
742
                        }
699
743
                        
700
 
                        int dockSize = (drag_resizing) ? Width : MinimumDockArea.Width;
 
744
                        int dockSize = (DnDTracker.DragResizing) ? Width : MinimumDockArea.Width;
701
745
                        
702
746
                        switch (DockPreferences.Orientation) {
703
747
                        case DockOrientation.Bottom:
724
768
                        PainterOverlayVisible = false;
725
769
                        interface_change_time = DateTime.UtcNow;
726
770
                        
727
 
                        RegisterGtkDragSource ();
 
771
                        DnDTracker.Enable ();
728
772
                        window.UnpresentWindow ();
729
 
 
 
773
                        
730
774
                        SetParentInputMask ();
731
775
                        AnimatedDraw ();
732
776
                }
733
777
                
734
778
                public override void Dispose ()
735
779
                {
736
 
                        disposed = true;
 
780
                        DockServices.UnregisterService (drawing_service).Dispose ();
 
781
                        
737
782
                        UnregisterEvents ();
738
 
                        UnregisterGtkDragSource ();
 
783
                        DnDTracker.Disable ();
739
784
 
 
785
                        AutohideTracker.Dispose ();
 
786
                        CursorTracker.Dispose ();
 
787
                        DnDTracker.Dispose ();
740
788
                        PositionProvider.Dispose ();
741
789
                        AnimationState.Dispose ();
742
790
                        PopupMenu.Destroy ();
 
791
                        PopupMenu.Dispose ();
743
792
 
744
793
                        PositionProvider = null;
745
794
                        AnimationState = null;
764
813
                        
765
814
                        window = null;
766
815
                        
767
 
                        if (cursor_timer > 0)
768
 
                                GLib.Source.Remove (cursor_timer);
769
 
                        
770
816
                        if (animation_timer > 0)
771
817
                                GLib.Source.Remove (animation_timer);
772
818