PythonScript - how to access mouse coordinates?
-
So I think the PythonScript should have a helper function, e.g. getmouseXY() for active editor surface. Otherwise the above mentioned Scintilla command can’t be used directly.
-
What about using scintilla *dwell* notification and setting a reasonable *dwelltimeout?
Cheers
Claudia -
The default dwell time is 10000000 milliseconds–too large to be useful so one assumes it is set with that value to be “out of the way”, i.e., never trigger.
So here’s some sample code to illustrate what Claudia mentioned; running it will show how the callbacks trigger:
editor.setMouseDwellTime(750) # set a more reasonable value than the default def callback_sci_DWELLEND(args): print "sci_DWELLEND", args editor.callback(callback_sci_DWELLEND, [SCINTILLANOTIFICATION.DWELLEND]) def callback_sci_DWELLSTART(args): print "sci_DWELLSTART", args editor.callback(callback_sci_DWELLSTART, [SCINTILLANOTIFICATION.DWELLSTART])
And here’s some sample output to the console for various mouse moves and pauses:
sci_DWELLSTART {'y': 74, 'position': 166, 'code': 2016, 'x': 599} sci_DWELLEND {'y': 74, 'position': 166, 'code': 2017, 'x': 599} sci_DWELLSTART {'y': 159, 'position': 350, 'code': 2016, 'x': 295} sci_DWELLEND {'y': 159, 'position': 350, 'code': 2017, 'x': 295} sci_DWELLSTART {'y': 151, 'position': -1, 'code': 2016, 'x': 303} sci_DWELLEND {'y': 151, 'position': -1, 'code': 2017, 'x': 303}
Maybe I still don’t understand the use-case…but that’s OK. :-)
-
@Scott-Sumner
Thanks. Your example worked. Still I can’t get it work for a real application.
Here is a script that I use for a test:def p(s): console.write(s) editor.setMouseDwellTime(0) p("hello") def callback_sci_DWELLEND(args): p("END") #editor.callback(callback_sci_DWELLEND, [SCINTILLANOTIFICATION.DWELLEND]) editor.callbackSync(callback_sci_DWELLEND, [SCINTILLANOTIFICATION.DWELLEND]) def callback_sci_DWELLSTART(args): p("START") #editor.callback(callback_sci_DWELLSTART, [SCINTILLANOTIFICATION.DWELLSTART]) editor.callbackSync(callback_sci_DWELLSTART, [SCINTILLANOTIFICATION.DWELLSTART]) notepad.clearCallbacks() editor.setMouseDwellTime(10000000)
So I tried also with
callbackSync
just hoping it helps, but it does not work either way.
Nothings happens - it only prints hello, but none of the callbacks register any event.
Could you look into it to make it work? -
Hmmmm…well with your last line it appears you are setting the dwell time to almost 3 hours??
So maybe you just need to be really patient to see it working…?
:-D -
@Scott-Sumner
:) maybe, I just don’t know how to handle event properly.So for now exactly what I want is: run the script, catch the event exactly ONCE, stop the script.
If I don’t close the script then it continues to work forever (only closing NPP can stop it)
and I should set DwellTime back to default I suppose? Wouldn’t it otherwise spam the events forever? -
You could set the dwell time to a big value INSIDE the event handler function body to effectively have it run once. Or clear the callback there…
The script itself ends pretty much immediately. However, by “giving” the event functions to Pythonscript, they are not always running, but rather are ready to run when the relevant events occur (e.g., dwelling the mouse, or moving it after dwelling). You can remove the events at any time (e.g. in another script, or in one script that both sets/clears the event handlers on every other run…).
-
@Scott-Sumner
Well, putting that inside the function stops the event firing.
Although any further experiments don’t give anything reasonable to be
able to make a working script. The function body runs more and more times after each script run,
so it just lives their its own life. And I don’t find any way to control or force it to
immediately update a global variable or run once. Restarting NPP helps
to flush the notification pool, still it does not help further.So I don’t know, probably I should try contact the plugin maintainer and ask to add
a function to get the mouse coordinates. -
…ask to add a function to get the mouse coordinates
I’m not sure why you think you can’t already get the mouse coordinates…?
So maybe a more complete example helps aid understanding…
Take a look at this script and run it:
try: installed except NameError: installed = False if not installed: def callback_sci_DWELLEND(_): print "mouse is on the MOVE again..." def callback_sci_DWELLSTART(args): doc_pos_info = word_info = '' if args['position'] != -1: doc_pos_info = '; document position is {}'.format(args['position']) start_of_word_pos = editor.wordStartPosition(args['position'], True) end_of_word_pos = editor.wordEndPosition(start_of_word_pos, True) if start_of_word_pos != end_of_word_pos: word_info = '; word pointed at is "{}"'.format(editor.getTextRange(start_of_word_pos, end_of_word_pos)) print "mouse PAUSED at coords ({x},{y}){p}{w}".format(x=args['x'], y=args['y'], p=doc_pos_info, w=word_info) editor.setMouseDwellTime(250) editor.callback(callback_sci_DWELLEND, [SCINTILLANOTIFICATION.DWELLEND]) editor.callback(callback_sci_DWELLSTART, [SCINTILLANOTIFICATION.DWELLSTART]) installed = True else: editor.clearCallbacks(callback_sci_DWELLEND) editor.clearCallbacks(callback_sci_DWELLSTART) editor.setMouseDwellTime(10000000) installed = False print 'installed:', installed
Here’s some example output from it:
The first time you run it it will print
Installed: True
and then as you move the mouse, theMOVE
/PAUSED
messages will appear on the console. This will persist until the second time you run it, at that time it will showInstalled: False
and the mouse-related console messages will stop. Run it yet again and it will “install” again, etc.I hope this helps solidify some of the concepts for you. :-)
-
@Scott-Sumner
Scott, thanks a lot for the time you invest.
Though I must admit the results the script gives are again
something far from what I try to achieve. I see you have
a lot of parsing already there, etc.I’ll try to explain it better.
All that I want: say, I have a script bound to Ctrl-X, or whatever key.
Now, once I press the key it runs the script and THIS happens:- get the mouse coordinate inside editor widget ONCE and immediately
- save the value (say, for simplicity, just Y coordinate) in a global variable (otherwise how I return it from the callback function to other scope?)
- use this variable out of the callback function part, say
print Y
it in the end of the script - exit the script, closing everything that was created there
So if you did not lose interest already…
That is all I want. And that should be enough to make all further
features based on mouse cursor position, e.g. swapping words, lines, etc.
And sorry if I was not very clear from the beginning. -
@Scott-Sumner
So, my last comment about the scope is not important - I can just write inside the
callback function further commands.The problem is that I cannot force start the DWELL even. It starts only if I MOVE
the mouse. Otherwise the script just sits there forever. That is the main problem.
And I don’t see how to make it just work immediately. So technically, it works, but in such a strange manner.
Probably there is some command to ‘ping’ the mouse from the script or something?
Anyway I suspect (but may be wrong) that those notifications are not intended for direct reading of mouse coordinates. -
I will have to assume you are making it harder than it needs to be. Perhaps only more and continued exposure to Pythonscript programming will help?
But in an effort to help you learn, I’d suggest 2 scripts–one that handles install/uninstall and gets the mouse coordinates and stores them in global variables (run this one first):
try: installed except NameError: installed = False if not installed: mouse_x = 0 mouse_y = 0 def callback_sci_DWELLSTART(args): global mouse_x, mouse_y mouse_x = args['x'] mouse_y = args['y'] editor.callback(callback_sci_DWELLSTART, [SCINTILLANOTIFICATION.DWELLSTART]) editor.setMouseDwellTime(0) installed = True else: editor.clearCallbacks(callback_sci_DWELLSTART) editor.setMouseDwellTime(10000000) installed = False print 'installed:', installed
And a second script that you bind to a keycombo that does your on-demand “what are the mouse coords right now?” :
print '({x},{y})'.format(x=mouse_x, y=mouse_y)
-
@Scott-Sumner
I am making it harder ? No, it is just harder than it should be, because there is
no function to read the mouse coordinate.Thanks a lot for another example. Yes the script works and that’s a good example how to use the global scope. Still this requires me to ‘install’ the script (using your terminology), i.e. run the script right away and keep it persistent for the whole working session. That may be OK, but that is just overkill and that is the point I was trying to make. So I would avoid this if it was possible.
To understand what I mean, try running the script without mouse movement and you’ll see the value (0,0), or the value from previously stopped session. -
Well, I tried my best. Sorry that I fell short.
:-(
I thought the end-goal was to achieve a solution to a problem, but reading back through I now understand that the goal was just to complain that there is no direct function to read the mouse coordinates.
I rather like pushing to a solution to a problem, because it moves something forward, and can be technically interesting/challenging. Complaining is just, well…what it is…
-
@Scott-Sumner
Your work is really appreciated. I have learned many new things, and those are perfect examples, I can use for now. Yes it’s a bit sad that there is lack of direct solution, so I’m complaining. Anyway I couldn’t know in advance, but probably there will appear something in the future? so why not complain a bit - that is how new features are starting their way. -
I may not have the technical expertise to fully understand all this, but I read this thread with some entertainment. I didn’t think I was gonna get the solution to my Logitech mouse problems (and I didn’t), but…
It was like watching a tennis match:
complaint (volley) solution
complaint (volley) solution
complaint (volley) solution
…It seems like a perfectly viable solution has been proposed, and you just don’t want to use it to make Notepad++ more productive for yourself. To me that seems a bit crazy.
try running the script without mouse movement
Wha??? The whole point (I thought) was that the mouse DOES MOVE…why else would you need/want its coordinates?
Just set up the callbacks at startup (in startup.py ?), never worry about turning it “off”, and just do what you wanna do with the data when the script run from the keycombo happens. YOU HAVE THE MOUSE X AND Y that you so preciously need.
Complainers never win…those that DO win. Whiners never even get noticed, even when they have a legit complaint.
-
@Alan-Kilborn said:
you just don’t want to use it to make Notepad++ more productive for yourself.
What makes you think I don’t want to use it?
Sure without alternatives I will use it, and if there’ll be a dedicated function
I’ll use it instead, end of story.
More important - what makes you think that scripting is there for myself?
What if I want to write common features that can help a lot of people?
Which is obviously the case with such functionality.
And they probably already define the ‘DwellTime’ for pop-up tips or something? According to Scintilla docs that seems to be the purpose. (though I haven’t
tested it yet).To me that seems a bit crazy.
No comment
Complainers never win…those that DO win. Whiners never even get noticed, even when they have a legit complaint.
If that was adressed to me - then, mr. philosopher, tell me who are those
who complain about “complainers” and make arbitrarily labeling? -