Page 1 of 1

Show / hide cursor

Posted: Mon Aug 06, 2018 7:23 am
by Papala
Hi, does anyone know if their's a way (like showcurosr() in windows) to show or hide the cursor on a window ?
I'm using the windowmouseX/Y to display my mouse sprite in a 2D screen to avoid high DPI mouse "bug" so my "game" is (for now) windows only just because of this API request.
(If anyone know the same tric on macOS, i'm intrested too.)

Thx.

Re: Show / hide cursor

Posted: Mon Aug 06, 2018 9:19 am
by Shardik
In order to hide the cursor in Linux you have to change the cursor to #GDK_BLANK_CURSOR (tested successfully on Linux Mint 19 x86 'Tara' with Cinnamon using PB 5.46 x86 in ASCII and Unicode mode with GTK2 and GTK3):

Code: Select all

EnableExplicit

#GDK_BLANK_CURSOR = -2

ImportC ""
  gtk_widget_get_window(*Widget.GtkWidget)
EndImport

Procedure HideCursor(HideCursor.I = #True)
  Protected Cursor.I

  If HideCursor
    Cursor = gdk_cursor_new_(#GDK_BLANK_CURSOR)
  Else
    Cursor = gdk_cursor_new_(#GDK_ARROW)
  EndIf

  gdk_window_set_cursor_(gtk_widget_get_window(WindowID(0)), Cursor)
EndProcedure

ProcedureC KeyPressCallback(*Widget.GtkWidget, *Event.GdkEventKey, *UserData)
  Protected Key.L

  Key = *Event\keyval & $FF

  If Key = #ESC
    HideCursor(#False)
  EndIf
EndProcedure   

OpenWindow(0, 200, 100, 200, 100, "Hide cursor demo")
ButtonGadget(0, 30, 20, 140, 25, "Hide cursor")

CreateStatusBar(0, WindowID(0))
AddStatusBarField(#PB_Ignore)
StatusBarText(0, 0, "Press <Esc> to show cursor", #PB_StatusBar_Center)
g_signal_connect_(WindowID(0), "key_press_event", @KeyPressCallback(), 0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
        HideCursor(#True)
      EndIf
  EndSelect
ForEver

Re: Show / hide cursor

Posted: Mon Aug 06, 2018 11:18 am
by #NULL
Thanks Shardik. Works here too with PB570b1 x64, Ubuntu 16.04, xfce, gtk3/gtk2.

Re: Show / hide cursor

Posted: Mon Aug 06, 2018 12:59 pm
by Shardik
#NULL wrote:Thanks Shardik. Works here too with PB570b1 x64, Ubuntu 16.04, xfce, gtk3/gtk2.
Thank you for your testing and feedback!

Re: Show / hide cursor

Posted: Mon Aug 06, 2018 3:21 pm
by Shardik
This is a cross-platform example to hide and show the cursor. I successfully tested it on these operating systems:
- Fedora 27 x86 with Gnome 3 and PB 5.46 x86 in ASCII and Unicode mode with GTK3 (for GTK2 take a look into Update 2 below)
- Kubuntu 18.04 x86 with KDE and PB 5.46 x86 in ASCII and Unicode mode with GTK2 and GTK3
- Linux Mint 18.3 x64 'Sylvia' with Cinnamon and PB 5.46 x64 in ASCII and Unicode mode
- MacOS 10.6.8 'Snow Leopard' with PB 5.46 x86 in ASCII and Unicode mode
- Windows 7 x64 with PB 5.46 x86 and x64 in ASCII and Unicode mode

Code: Select all

EnableExplicit

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  #GDK_BLANK_CURSOR = -2
 
  ImportC ""
    gtk_widget_get_window(*Widget.GtkWidget)
  EndImport
CompilerEndIf
 
Procedure HideCursor(HideCursor.I = #True)
  Protected Cursor.I
 
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Linux
      If HideCursor
        Cursor = gdk_cursor_new_(#GDK_BLANK_CURSOR)
      Else
        Cursor = 0
      EndIf
     
      gdk_window_set_cursor_(gtk_widget_get_window(WindowID(0)), Cursor)
    CompilerCase #PB_OS_MacOS
      If HideCursor
        CocoaMessage(0, 0, "NSCursor hide")
      Else
        CocoaMessage(0, 0, "NSCursor unhide")
      EndIf
    CompilerCase #PB_OS_Windows
      If HideCursor
        ShowCursor_(#False)
      Else
        ShowCursor_(#True)
      EndIf
  CompilerEndSelect
EndProcedure

OpenWindow(0, 200, 100, 200, 100, "Hide cursor demo")
ButtonGadget(0, 30, 20, 140, 25, "Hide cursor")

CreateStatusBar(0, WindowID(0))
AddStatusBarField(#PB_Ignore)
StatusBarText(0, 0, "Press <Esc> to show cursor", #PB_StatusBar_Center)

AddKeyboardShortcut(0, #PB_Shortcut_Escape, 0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
        HideCursor(#True)
        DisableGadget(0, #True)
      EndIf
    Case #PB_Event_Menu
      If EventMenu() = 0
        HideCursor(#False)
        DisableGadget(0, #False)
      EndIf
  EndSelect
ForEver
Update 1: For Linux I have changed

Code: Select all

Cursor = gdk_cursor_new_(#GDK_ARROW)
to

Code: Select all

Cursor = 0
in order to restore the default cursor after having pressed the <Esc> key.

Update 2: In order to run the example on the Linux distribution Fedora 27 x86 with Gnome 3 and GTK2 you have to add the following declarations to the ImportC..EndImport block:

Code: Select all

    gdk_cursor_new(CursorType.L)
    gdk_window_set_cursor(*GdkWindow, *Cursor.GdkCursor)
and you have delete the trailing underscores when calling these functions.

Re: Show / hide cursor

Posted: Mon Aug 06, 2018 5:34 pm
by Papala
Can't test macOS yet but for linux it work ! Thank you a lot Shardik !!

Re: Show / hide cursor

Posted: Mon Aug 06, 2018 9:16 pm
by Sicro
On my Manjaro Linux (gtk3) the normal mouse cursor is not restored correctly:

Image

Edit:
If I replace "#GDK_ARROW" with "#GDK_LEFT_PTR", it works correctly.
But there is also "#GDK_RIGHT_PTR" so it is best to save the current mouse cursor so that it can be restored correctly.

Re: Show / hide cursor

Posted: Mon Aug 06, 2018 9:17 pm
by Dude
@Shardik: the Windows version, ShowCursor_(#False), only works for the current window. As soon as you move the mouse away from it, it becomes visible again. Just in case you weren't aware.

Re: Show / hide cursor

Posted: Tue Aug 07, 2018 9:53 am
by Papala
@Shardik: the Windows version, ShowCursor_(#False), only works for the current window. As soon as you move the mouse away from it, it becomes visible again. Just in case you weren't aware.
That's what i asked for, but thank for the warn.
so it is best to save the current mouse cursor so that it can be restored correctly.
Does something like gdk_window_get_cursor_() work for this ? (I'm realy new with linux... ^^")

Re: Show / hide cursor

Posted: Tue Aug 07, 2018 10:44 am
by Shardik
Sicro wrote:On my Manjaro Linux (gtk3) the normal mouse cursor is not restored correctly
Thank you for your bug report. I expected this problem already to appear. I hope to have found a solution by changing

Code: Select all

Cursor = gdk_cursor_new_(#GDK_ARROW)
to

Code: Select all

Cursor = 0
This should set the default cursor. I have changed this also in my cross-platform example above.

Re: Show / hide cursor

Posted: Tue Aug 07, 2018 12:32 pm
by Dude
Papala wrote:That's what i asked for
Oops, I didn't realize. My bad. :oops:

Re: Show / hide cursor

Posted: Tue Aug 07, 2018 4:45 pm
by Papala
Shardik wrote:This should set the default cursor.
Work fine with Debian 8.

Re: Show / hide cursor

Posted: Tue Aug 07, 2018 5:05 pm
by Sicro
Thank you, Shardik, now it works :)