@@ -34,12 +34,21 @@ namespace ColorPicker.Widgets {
3434 const string bright_border_color_string = " #FFFFFF" ;
3535 private Gdk . RGBA bright_border_color = Gdk.RGBA ();
3636
37- int snapsize = 35 ; // must be odd to have a 1px magnifier center
37+ // 1. Snapsize is the amount of pixel going to be magnified by the zoomlevel.
38+ // 2. The snapsize must be odd to have a 1px magnifier center.
39+ // 3. Asure that snapsize*max_zoomlevel+shadow_width*2 is smaller than 2 * get_screen ().get_display ().get_maximal_cursor_size()
40+ // Valid: snapsize = 31, max_zoomlevel = 7, shadow_width = 15 --> 247px
41+ // get_maximal_cursor_size = 128 --> 256px
42+ // Otherwise the cursor starts to flicker. See https://github.com/stuartlangridge/ColourPicker/issues/6#issuecomment-277972290
43+ // and https://github.com/RonnyDo/ColorPicker/issues/19
44+ int snapsize = 31 ;
3845 int min_zoomlevel = 2 ;
39- int max_zoomlevel = 9 ;
46+ int max_zoomlevel = 7 ;
4047 int zoomlevel = 3 ;
48+ int shadow_width = 15 ;
4149
42-
50+ private Gdk . Cursor magnifier = null ;
51+
4352 construct {
4453 type = Gtk . WindowType . POPUP ;
4554 }
@@ -51,7 +60,8 @@ namespace ColorPicker.Widgets {
5160 set_deletable (false );
5261 set_skip_taskbar_hint (true );
5362 set_skip_pager_hint (true );
54- set_keep_above (true );
63+ set_keep_above (true );
64+
5565
5666 dark_border_color. parse (dark_border_color_string);
5767 bright_border_color. parse (bright_border_color_string);
@@ -78,13 +88,12 @@ namespace ColorPicker.Widgets {
7888 }
7989
8090
81- public override bool draw (Cairo .Context cr ) {
82-
91+ public override bool draw (Cairo .Context cr ) {
8392 return false ;
8493 }
8594
8695
87- public override bool motion_notify_event (Gdk .EventMotion e ) {
96+ public override bool motion_notify_event (Gdk .EventMotion e ) {
8897 Gdk . RGBA color = get_color_at ((int ) e. x_root, (int ) e. y_root);
8998 moved (color);
9099
@@ -121,19 +130,21 @@ namespace ColorPicker.Widgets {
121130 int px, py;
122131 get_pointer (out px, out py);
123132
124- int shadow_width = 15 ;
125133 var radius = snapsize * zoomlevel / 2 ;
126134
127135 // take screenshot
136+
128137 var latest_pb = snap (px - snapsize / 2 , py - snapsize / 2 , snapsize, snapsize);
129138
130139 // Zoom that screenshot up, and grab a snapsize-sized piece from the middle
131140 var scaled_pb = latest_pb. scale_simple (snapsize * zoomlevel + shadow_width * 2 , snapsize * zoomlevel + shadow_width * 2 , Gdk . InterpType . NEAREST );
132141
142+
133143 // Create the base surface for our cursor
134144 var base_surface = new Cairo .ImageSurface (Cairo . Format . ARGB32 , snapsize * zoomlevel + shadow_width * 2 , snapsize * zoomlevel + shadow_width * 2 );
135145 var base_context = new Cairo .Context (base_surface);
136146
147+
137148 // Create the circular path on our base surface
138149 base_context. arc (radius + shadow_width, radius + shadow_width, radius, 0 , 2 * Math . PI );
139150
@@ -145,9 +156,9 @@ namespace ColorPicker.Widgets {
145156 base_context. clip_preserve ();
146157 base_context. paint ();
147158 base_context. restore ();
159+
148160
149-
150- // Draw a shadow as outside magnifier border
161+ // Draw a shadow as outside magnifier border
151162 double shadow_alpha = 0.6 ;
152163 base_context. set_line_width (1 );
153164
@@ -158,7 +169,8 @@ namespace ColorPicker.Widgets {
158169 shadow_color. alpha = shadow_alpha / ((shadow_width - i + 1 )* (shadow_width - i + 1 ));
159170 Gdk . cairo_set_source_rgba (base_context, shadow_color);
160171 base_context. stroke ();
161- }
172+ }
173+
162174
163175 // Draw an outside bright magnifier border
164176 Gdk . cairo_set_source_rgba (base_context, bright_border_color);
@@ -188,35 +200,38 @@ namespace ColorPicker.Widgets {
188200
189201 // turn the base surface into a pixbuf and thence a cursor
190202 var drawn_pb = Gdk . pixbuf_get_from_surface(base_surface, 0 , 0 , base_surface. get_width(), base_surface. get_height());
191- var zoom_pb = drawn_pb. scale_simple(
192- snapsize * zoomlevel, snapsize * zoomlevel, Gdk . InterpType . TILES );
193-
194- print (" drawn_pb width: " + drawn_pb. get_width(). to_string () + " \n " );
195- print (" zoom_pb width: " + zoom_pb. get_width(). to_string () + " \n " );
196- print (" radius is: " + radius. to_string () + " \n " );
197203
198- var magnifier = new Gdk .Cursor .from_pixbuf(
204+ magnifier = new Gdk .Cursor .from_pixbuf(
199205 get_screen (). get_display (),
200206 drawn_pb,
201- zoom_pb. get_width() / 2 ,
202- zoom_pb. get_height () / 2 );
203-
204- // Set the cursor
207+ drawn_pb. get_width () / 2 ,
208+ drawn_pb. get_height () / 2 );
209+
210+ /*
211+ uint max_cursor_width, max_cursor_height, default_cursor_width, default_cursor_height;;
212+ get_screen ().get_display ().get_maximal_cursor_size (out max_cursor_width, out max_cursor_height);
213+ print ("\n\nCursor size is " + drawn_pb.get_width().to_string () + "x" + drawn_pb.get_height().to_string ());
214+ print ("\nAllowed size is " + max_cursor_width.to_string () + "x" + max_cursor_height.to_string ());
215+ print ("\nDefault size is " + get_screen ().get_display ().get_default_cursor_size ().to_string ());
216+ */
217+
218+ // Set the cursor
205219 var manager = Gdk . Display . get_default (). get_device_manager ();
206- manager. get_client_pointer (). grab(
220+ manager. get_client_pointer (). grab (
207221 get_window (),
208222 Gdk . GrabOwnership . APPLICATION ,
209223 true ,
210224 Gdk . EventMask . BUTTON_PRESS_MASK | Gdk . EventMask . POINTER_MOTION_MASK | Gdk . EventMask . SCROLL_MASK ,
211225 magnifier,
212- Gdk . CURRENT_TIME );
226+ Gdk . CURRENT_TIME );
227+
213228 }
214229
215230
216231 public Gdk .Pixbuf ? snap (int x , int y , int w , int h ) {
217232 var root = Gdk . get_default_root_window ();
218233
219- var screenshot = Gdk . pixbuf_get_from_window (root, x, y, w, h);
234+ var screenshot = Gdk . pixbuf_get_from_window (root, x, y, w, h);
220235 return screenshot;
221236 }
222237
@@ -255,8 +270,7 @@ namespace ColorPicker.Widgets {
255270
256271
257272 public override void show_all () {
258- base . show_all ();
259-
273+ base . show_all ();
260274
261275 var manager = Gdk . Display . get_default (). get_device_manager ();
262276 var pointer = manager. get_client_pointer ();
0 commit comments