Question

I want to continually track the mouse as it moves, or at least every 0.5 seconds:

require "curses"
include Curses



init_screen
start_color
init_pair(COLOR_BLUE,COLOR_BLUE,COLOR_WHITE)
init_pair(COLOR_RED,COLOR_RED,COLOR_WHITE)
crmode
noecho
stdscr.keypad(true)

close = false

begin
  mousemask(BUTTON1_CLICKED|BUTTON2_CLICKED|BUTTON3_CLICKED|BUTTON4_CLICKED)

  count = 0

  while( count < 10 )

        sleep 0.5

          m = getmouse


          winx = Window.new(7,30,10,10)
          winx.keypad = true
          winx.box(?|, ?-, ?+)
          winx.setpos(2,3)
          winx.addstr "Loop Count: " + count.to_s
          winx.setpos(3,3)
          winx.addstr "Mouse Position: " + m.inspect



          winx.refresh


          count += 1
  end


refresh
ensure
    close_screen
end

I think I'm close, but for some reason, getmouse is returning nill? Why is this? Does getmouse only work after an event such as a click? If so, is it impossible to continually track the mouse?

This from the ruby documentation

getmouse() click to toggle source

Returns coordinates of the mouse.

This will read and pop the mouse event data off the queue

See the BUTTON*, ALL_MOUSE_EVENTS and REPORT_MOUSE_POSITION constants

REPORT_MOUSE_POSITION appears to be key here, but I really don't know how to use these constants. getmouse(REPORT_MOUSE_POSITION) doesn't work..sorry if that's majorly nooby, but there isn't much documentation out there.

Was it helpful?

Solution

You need to add REPORT_MOUSE_POSITION to your mousemask:

mousemask(BUTTON1_CLICKED|BUTTON2_CLICKED|BUTTON3_CLICKED|BUTTON4_CLICKED|REPORT_MOUSE_POSITION)

Or perhaps just

mousemask(ALL_MOUSE_EVENTS)

Curses processes mouse clicks in the same stream as key presses. So you need to get your mouse events with getch.

In your case, I recommend setting getch to non-blocking read stdscr.timeout=0 and adding a case statement:

case getch
when KEY_MOUSE
  m = getmouse
  winx.addstr "Mouse Position: #{m.x} #{m.y} #{m.z}"
end

Unfortunately on my system this only reports mouse movement when I click, so you might be out of luck depending on your curses implementation/terminal.

If you aren't too afraid of C, I recommend reading the ncurses C documentation. Ruby's curses library is basically a direct translation of it.

OTHER TIPS

According to the TLDP nurses documentation, you need to use REPORT_MOUSE_POSITION Asa constant in your mouse mask. Try this:

mousemask(REPORT_MOUSE_POSITION|BUTTON1_CLICKED|BUTTON2_CLICKED|BUTTON3_CLICKED|BUTTON4_CLICKED)

This tells curses to report the mouse position as an event.

See the answer to Mouse movement events in NCurses.

Mouse event reporting depends heavily on the terminal emulator (on a Mac in iTerm2, I had to "Enable xterm mouse reporting" in preferences), and on the TERM settings as described above (I had to launch ruby like TERM=xterm-1003 ruby curses_mouse.rb)

Also, you must call getch and test for KEY_MOUSE before calling getmouse. For example, if you're only interested in mouse events:

c = getch
case c
when KEY_MOUSE
  m = getmouse
end

Also, add |REPORT_MOUSE_POSITION to mousemask call.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top