Search code examples
pythongtkgtk3pygtk

Why do I get fractional values for mouse position in button-press-event?


I'm trying to handle mouse events in my application, but I do not understand why x and y in my events are fractional (I expected mouse position to contain integers).

Simple application I used to test it:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk

class Example(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.set_default_size(800, 600)

        drawing_area = Gtk.DrawingArea();
        drawing_area.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)
        drawing_area.connect("button-press-event", self.handle_image_click)
        self.add(drawing_area)

    def handle_image_click(self, widget, event):
        print("click", event.x, event.y)

win = Example()
win.show_all()
Gtk.main()

Example output:

click 734.751708984375 306.2582092285156
click 631.0667114257812 416.09857177734375
click 435.015625 462.9517822265625

I'm using Gtk 3.24.20 and python-gobject 3.36.1. What could be the reason for such behavior?


Solution

  • Event coordinates come from the windowing system, and windowing systems can provide sub-pixel precision for pointer coordinates. Additionally, GTK will normalise the event coordinates to handle HiDPI scaling factors, which means that the logical position might have a fractional component even if the physical coordinate does not.

    You can round the event coordinates to align to the pixel grid, if you want, by using either floor() or ceil().