how to get mouse cursor - Kivy 2.0.0 Raspberry Pi no desktop

84 views
Skip to first unread message

mjk...@gmail.com

unread,
Jun 2, 2021, 7:31:51 PM6/2/21
to Kivy users support
how can I get a mouse cursor?

I am using 32-bit stock Raspberry Pi OS on a Raspberry Pi 3B+

I installed Python 3.9.5 but did not replace the system python and installed my libraries in a virtual environment.  I also installed Kivy while in the virtual environment and did have to do a bit of manual work to have the libraries found - all worked out ok in the end.

The graphics are working, nominally.

I know that prior to Kivy 1.11 there was a Python based module for putting a mouse cursor on the desktop and I used that at the time.   Last year before Kivy 2.0 I think the installations 'just worked' without the use of that module.

The mouse function seems to work because I can left-click and occasionally cause an action by accident but as mentioned there is no graphic for the mouse cursor.

I attached a log
kivy_load_ok_no_mouse.txt

mjk...@gmail.com

unread,
Jun 3, 2021, 3:31:26 PM6/3/21
to Kivy users support
wish to add that I loaded the version of Raspberry pi OS that has a desktop (NOT the Lite version) but I am not using it that way.  I changed the setting to boot to the command line console.

I like to retain the ability to load a desktop interface for file management but this is not critical.  It is more important to have a mouser cursor.  about 1 year ago with a lot of trial/error and some help from this group I got a Raspberry Pi 4 running like this and I know the mouser cursor is functioning but I somehow lost track of what I did.  and the *something* would be different anyway since I am working with a Raspberry pi 3B+ now.

anyone have ideas about this?  do I need to change the Windowing system (backend) or do I need to go back and use the cursor module like I did many years back with the first systems I made?

or - I could go back to Kivy 1.11.  I only loaded the new one because I assumed it would be better and I am sure it is except I have this one critical thing missing : (

mjk...@gmail.com

unread,
Jun 5, 2021, 10:41:06 AM6/5/21
to Kivy users support
OK, solved this the old way - using the cursor module - and it works smoother than the mouse cursor on my other setup that had not required it.
in the .ini file:

[input]
%(name)s = probesysfs,provider=hidinput
[modules]
mycursor = texture = cursor.png,size = 32x32

for my setup I redirect the KIVY_HOME variable to be part of my project or git repo and then copy the cursor.py module from the kivy installation folders into my local one
/my_kivy_home/mods/mycursor.py


I did some optimizations for performance - below and added the ability to pass the exact display size and then one could
switch out the mouse function as desired.  my setup is a machine that has to perform fast so I desired to reduce the
overhead as much as I could


__all__ = ('start', 'stop')

from kivy.core.image import Image
from kivy.graphics import Color, Rectangle
from kivy import kivy_data_dir
from kivy.compat import string_types
from os.path import join
from functools import partial

# this is of course hard-coded to a certain screen size
# to use a different screen size copy and edit this function and change the displaywy
# parameter sent from the ini file
def _mouse_move_constrain(win, pos, /):
    _x = pos[0]
    _y = pos[1] - 26
    # some constraints just to keep the cursor on the screen but they are not strictly necessary
    if _x > 1910:
        _x = 1910

    if _y < -21:
        _y = -21

    win._cursor.pos = _x, _y

def _mouse_move_free(win, pos, /):
    #
    win._cursor.pos = pos[0], pos[1]


def _mouse_move(texture, size, display_size, win, pos, *args):

    global startup_fun

    if hasattr(win, '_cursor'):
        # this is unlikely to run because we unbind this function on first call
        c = win._cursor
        c.pos = pos[0], pos[1] - 32
    else:
        # this is going to run ONE time per program run
        with win.canvas.after:
            Color(1, 1, 1, 1, mode='rgba')
            win._cursor = c = Rectangle(texture=texture, size=size)
            win.unbind(mouse_pos=startup_fun)
            print("display size passed to $KIVY_HOME/mods/mycursor.py module is: {}".format(display_size))
            if display_size == [1920, 1080]:
                win.bind(mouse_pos=_mouse_move_constrain)
            else:
                win.bind(mouse_pos=_mouse_move_free)

"""
Start/stop are functions that will be called for every window opened in Kivy. When you are starting a module, you can
use these to store and manage the module state. Use the ctx variable as a dictionary. This context is unique for each
instance/start() call of the module, and will be passed to stop() too.
"""
def start(win, ctx):
    global startup_fun
    # this will run when Kivy is loaded - one time
    cursor_texture = Image(
        ctx.config.get('texture', join(kivy_data_dir, 'images', 'cursor.png'))
    ).texture
    cursor_size = ctx.config.get('size')
    if isinstance(cursor_size, string_types):
        cursor_size = [int(x) for x in cursor_size.split('x')]
    elif not cursor_size:
        cursor_size = cursor_texture.size

    # make sure to include a default size
    displaywh = ctx.config.get('displaywh', [1920, 1080])
    if isinstance(displaywh, string_types):
        displaywh = [int(x) for x in displaywh.split('x')]

    startup_fun = partial(_mouse_move, cursor_texture, cursor_size, displaywh)
    win.bind(mouse_pos=startup_fun)


def stop(win, ctx):
    # unknown if this ever runs.  maybe if there is a way to unload the module then it will
    win.unbind(mouse_pos=_mouse_move_constrain)
Reply all
Reply to author
Forward
0 new messages