PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/docky-2.0.12/Docky/Docky/Interface/CursorTracker.cs

#
C# | 166 lines | 114 code | 35 blank | 17 comment | 18 complexity | 2d099b99f3229f33f68ebbadcaa13fb1 MD5 | raw file
Possible License(s): GPL-3.0
  1. //
  2. // Copyright (C) 2009 Jason Smith
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. //
  17. using System;
  18. using System.Collections.Generic;
  19. using System.ComponentModel;
  20. using System.Linq;
  21. using System.Text;
  22. using Cairo;
  23. using Gdk;
  24. using Gtk;
  25. namespace Docky.Interface
  26. {
  27. public class CursorTracker
  28. {
  29. static Dictionary<Gdk.Display, CursorTracker> trackers = new Dictionary<Gdk.Display, CursorTracker> ();
  30. public static CursorTracker ForDisplay (Gdk.Display display)
  31. {
  32. if (!trackers.ContainsKey (display))
  33. trackers [display] = new CursorTracker (display);
  34. return trackers [display];
  35. }
  36. const uint LowResTimeout = 250;
  37. const uint HighResTimeout = 20;
  38. Gdk.Display display;
  39. DateTime last_update;
  40. List<object> resolution_senders;
  41. uint timer;
  42. uint timer_speed;
  43. public event EventHandler<CursorPostionChangedArgs> CursorPositionChanged;
  44. public Gdk.Point Cursor { get; private set; }
  45. public ModifierType Modifier { get; private set; }
  46. public Gdk.Screen Screen { get; private set; }
  47. public bool Enabled { get; set; }
  48. CursorTracker (Gdk.Display display)
  49. {
  50. Enabled = true;
  51. this.display = display;
  52. resolution_senders = new List<object> ();
  53. ResetTimer ();
  54. }
  55. public void RequestHighResolution (object sender)
  56. {
  57. resolution_senders.Add (sender);
  58. if (timer_speed == HighResTimeout)
  59. return;
  60. ResetTimer ();
  61. }
  62. public void CancelHighResolution (object sender)
  63. {
  64. resolution_senders.Remove (sender);
  65. if (resolution_senders.Any ())
  66. return;
  67. ResetTimer ();
  68. }
  69. public void SendManualUpdate (Gdk.EventCrossing evnt)
  70. {
  71. // we get screwy inputs sometimes
  72. if (Math.Abs (evnt.XRoot - Cursor.X) > 100 || Math.Abs (evnt.YRoot - Cursor.Y) > 100) {
  73. OnTimerTick ();
  74. return;
  75. }
  76. Update (evnt.Window.Screen, (int) evnt.XRoot, (int) evnt.YRoot, evnt.State);
  77. }
  78. public void SendManualUpdate (Gdk.EventMotion evnt)
  79. {
  80. if (Math.Abs (evnt.XRoot - Cursor.X) > 100 || Math.Abs (evnt.YRoot - Cursor.Y) > 100) {
  81. OnTimerTick ();
  82. return;
  83. }
  84. Update (evnt.Window.Screen, (int) evnt.XRoot, (int) evnt.YRoot, evnt.State);
  85. }
  86. void ResetTimer ()
  87. {
  88. uint length = resolution_senders.Any () ? HighResTimeout : LowResTimeout;
  89. if (timer_speed != length) {
  90. if (timer > 0)
  91. GLib.Source.Remove (timer);
  92. if (!UserArgs.NoPollCursor)
  93. timer = GLib.Timeout.Add (length, OnTimerTick);
  94. timer_speed = length;
  95. }
  96. }
  97. bool OnTimerTick ()
  98. {
  99. if ((DateTime.UtcNow - last_update).TotalMilliseconds < 10) {
  100. return true;
  101. }
  102. int x, y;
  103. ModifierType mod;
  104. Gdk.Screen screen;
  105. display.GetPointer (out screen, out x, out y, out mod);
  106. Update (screen, x, y, mod);
  107. return true;
  108. }
  109. void Update (Gdk.Screen screen, int x, int y, Gdk.ModifierType mod)
  110. {
  111. last_update = DateTime.UtcNow;
  112. if (!Enabled)
  113. return;
  114. Gdk.Point lastPostion = Cursor;
  115. Cursor = new Gdk.Point (x, y);
  116. Modifier = mod;
  117. Screen = screen;
  118. if (lastPostion != Cursor)
  119. OnCursorPositionChanged (lastPostion);
  120. }
  121. void OnCursorPositionChanged (Gdk.Point oldPoint)
  122. {
  123. if (CursorPositionChanged != null) {
  124. CursorPostionChangedArgs args = new CursorPostionChangedArgs {
  125. LastPosition = oldPoint,
  126. };
  127. CursorPositionChanged (this, args);
  128. }
  129. }
  130. }
  131. }