How can I tell Windows not to do unhelpful pre-processing on tablet pen events?
I am programming in Python 2.6, targetting tablet PCs running Windows 7 (though I would like my program to work with little modification on XP with a SMART interactive whiteboard, and for mouse users on Linux/Mac). I've written a program which hooks into the normal Windows mouse events, WM_MOUSEMOVE etc., and writes on a canvas.
The problem is that the mouse messages are being fiddled with before they reach my application. I found that if I make long strokes and pause between strokes then the mouse messages are sent properly. But if I make several rapid short strokes, then something is doing unhelpful pre-processing. Specifically, if I make a down-stroke about 10 pixels long, and then make another downstroke about five pixels to the right of the first, then the second WM_MOUSEDOWN reports that it comes from exactly the same place as the first.
This looks like some sort of pre-processing, perhaps so that naive applications don't get confused about double-clicks. But for my application, where I want very faithful response to rapid gestures, it's unhelpful.
I found a reference to the MicrosoftTabletPenServiceProperty atom, and to CS_DBLCLKS window style, and I turned them both off with the following piece of Python code:
hwnd = self.GetHandle()
tablet_atom = "MicrosoftTabletPenServiceProperty"
atom_ID = windll.kernel32.GlobalAddAtomA(tablet_atom)
windll.user32.SetPropA(hwnd,tablet_atom,1)
currentstyle = windll.user32.GetClassLongA(hwnd, win32con.GCL_STYLE)
windll.user32.SetClassLongA(hwnd, win32con.GCL_STYLE, currentstyle & ~win32con.CS_DBLCLKS)
But it has no effect.
I tried writing a low-level hook for the mouse driver, with SetWindowsHookEx, but it doesn't work -- obviously the mouse messages are being pre-processed even before they are sent to my low-level Windows hook.
I would be very grateful for advice about how to turn off this pre-processing. I do not want to switch to RealTimeStylus -- first because it won't work on Windows XP plus SMART interactive whiteboard, second because I can't see how to use RealTimeStylus in CPython, so I would need to switch to IronPython, and then my code would no longer run on Linux/Mac.
Damon.
For raw mouse messages, you can use WM_INPUT on XP and later. Seven added some touch specific stuff: WM_GESTURE and WM_TOUCH
Related
SHORT VERSION:
I'm attempting to detect when my microphone is being captured by a program like Discord, preferably in Python, but I can't figure out how to do it. Any suggestions?
LONG VERSION:
I'm trying to write a program that will turn on an "On Air" light whenever my microphone is being used. Typically this would either be for Discord or Twitch. This is something Windows already monitors as well (Windows 10) because it displays a microphone icon down in the notifications tray and tells you what programs are using your microphone. Basically, whenever that icon notification is up, I want my light to be turned on.
The light is currently being run by sending serial commands through Python to an Arduino Nano, but I can only manually tell it to turn on or off.
I can't find a way to access windows privacy monitoring status or make any headway on just checking if a microphone is in use with Python. Any suggestions?
You can lock if the MicrophonIcon is displayed. Presice write an Pythonscript that locks if Pixel at the Position of the MicrophoneIcon having the Color off the MicrophonIcon. qt can do this. It has a python binding.
Get the Position of the MicrophonIcon( you can hover over it with the mouse and use a program to look the position up)
Get some Pixel Colors off the aria with qt
write a loop that checks if the Pixel Colors at the moment are equal to messured ones.
Con: if the Position off the Microphon changes(Screensize, other options that push it, not visable( fullscreen)) It will not work.
If you checke the yello lines in 2 loops it should define the Microphone icon nearly failsafe if the position isnt changing
I am trying to create a window in python where I will be displaying the status of a large system, a bunch of numbers or some LEDs. The idea is that the system sends messages to the display thread and the thread updates different parts of the window, like displaying a number or turning the color of a field. More importantly, the user interacts with system via command line of python interpreter, e.g. executing commands or updating variables.
One may simply suggest that I need to use one of the GUI packages, like pyqt or xwpython. But these modules are designed to build GUIs, that means they have plenty of resources to handle events moues clicks and so on, which I don't need. Also, these modules run a event loop which is a waste of resources as well as in many cases they block the python shell.
I tried to use pyqt without running the main loop. But when I do this windows thinks my application is not responding, and I get a bunch of problems. For example the close button on the window does not work, and any effort on closing it crashes my python session.
Any ideas on how I can implement my application?
Maybe you should consider to use the Apache's Superset dashboard.
Check this up:
https://superset.incubator.apache.org/installation.html
It makes amazing dashboards incredibly easy and useful.
I am really impressed by this MarlIO project and want to implement something similar using Python. However, I got the emulator OpenEmu working, however, I don't know how to control the game using Python.
Isn't it just a matter of sending a few keystrokes?! Man, it is not that straightforward on a Mac.
In [41]: cmd1
Out[41]: '\nosascript -e \'tell application "System Events" to key code 48 using {command down}\' \n'
In [42]: cmd2
Out[42]: '\nosascript -e \'tell application "System Events" to keystroke "a"\' \n'
I want to first use COMMAND+TAB to switch to the openEmu and then hit a to jump. However, when I ran the two commands, it only switched to the OpenEmu, looks like the keystroke a did not got sent.
However, when I ran 'cmd2' separately, it was clearly working.
Then I testedit against a different application - sublime, and it seemed to work there.
Can anyone point me to the right direction what I really did wrong with OpenEmu?
I did something like that a few months ago. The keystrokes are sent. However, System Event keystrokes last virtually no time, so the emulator's input mechanism doesn't pick them up.
I couldn't find a way to ask for a duration with AppleScript, so I ended up solving the problem using Quartz event taps, which let you do, for instance, "start pressing key, sleep 0.1s, stop pressing key". I did it in Swift, but you should be able to do it in Python with the ctype module.
Also note that it might be difficult to synchronize on a frame basis with the emulator. I raised that problem with the project maintainers, but I turned away because of the relatively cold response.
Using tk in my multi-threaded(*) console application causes it to crash without stacktrace, giving the message "Tcl_WaitForEvent: Notifier not initialized Abort trap".
The symptoms were that all my program's functions worked fine, until I brought up the tk window - then the very next operation would cause the crash.
Immediate searching found that Tkinter is not safe with respect to Python threads, so I made sure that I was not calling any Tk functions anywhere other than my main thread. The crashes continued.
I lost several hours because I believed that it was the specific command I was using that crashed the program - but eventually I realized that any keyboard input would crash the program.
After a lot of debugging, I finally boiled it down to a small program that demonstrates the issue, exposing what I believe is a bug or certainly a feature that needs documentation in the Tkinter library.
I was working on this posting I was debugging. I'm going to post it and answer my own question in the hopes that it will prevent the next person from wasting a day on it.
--
(* - Yes, it certainly needs to be multi-threaded. I have a thread for my socket connection, a thread that listens to a mic and finds levels, a thread to drive my serial port and more. In each case, the thing I'm reading on the thread naturally blocks most of the time.)
The solution!
The issue is that tk crashes if you read from Python's raw_input in a different thread from the tk thread!
A small program demonstrating the issue is here. If you run it, it gets keyboard input perfectly happily from the second thread - until you enter the command "tk" when it brings up an empty tk window. You can do whatever you like with that window - until you type in the console window and press return, when the whole program crashes.
Why am I reading from raw_input in a thread that isn't the main thread?
My program is a console application, but I'm controlling a lot of different parts, one of which is the pi3d OpenGL ES 2.0 graphics library which must be updated at or near the frame rate from the main Python thread.
How to work around it?
"Simple" enough - register for tk menu events and just get the keys directly! Except that's a crappy solution, because you have to emulate all those things that the console does for you already - deleting, left and right arrows and that sort of thing. But that's what I'll have to do.
Should the program become a fully-fledged tk application?
But I can't do that - the whole point of this program is that you can run it through a terminal window - often sshing into headless machines. I'm frankly more likely to make it a curses program!
The tk window is a minor part of the whole thing - just a window to show emulated lights when developing if you don't have the hardware hooked up (or don't want to keep flashing yourself in the face). I won't try to bring it up on headless machines, and that's fine.
Is this a bug?
I'm always loathe to attach such a label to software not my own, but I'm hard-pressed to come up with any other description. It causes a crash, and that crash produces no useful information of any type. I consider that Tkinter is somewhat lame for simply crashing when called from different threads, but at least this behavior is documented (if you dig down a little) - in this case, I'm calling a Python built-in, so I have no basis to expect that it will interact with this library at all, and there's no documentation of this problem.
Could there be a workaround?
I'm sort of hoping there will be a work-around - this one-page program was a single item on a long list of features has turned into a full-day head-scratching debugging session and I don't want to have to throw another day at least after this when none of this time is actually producing new features.
The best thing is if the tk team admitted this was a bug and came up with a fix. But I wouldn't expect that at my desktop before a year from now...
So perhaps the real best thing would be if there were some way to get tk to simply ignore the keyboard, and not crash. I did a tiny experiment with tk's "busy" but that didn't work and just doesn't seem to be the right sort of thing.
A little later, I'm now thinking about running the lighting as an independent program, a separate subprocess using Python's Subprocess library, and sending it text commands through stdin. This would be overkill if this were the only problem that was being solved, but in fact
Got it.
Replacing raw_input() with sys.stdin.readline() did the trick - at least in the demo (which I updated). Feel free to download this and experiment with it yourself!
I hope this saves someone else the time.
In my case (as mentioned in the comments under #Tom Swirly's answer) the solution was to switch to a non-interactive backend:
import matplotlib
matplotlib.use('Agg')
I'm trying to write an Xvfb-to-HTML5-canvas tool that will need to know when an X11 window changes so it can send a screen update to the client. Think of it like a web-based VNC or RDP but just for X11 windows (why send the whole desktop? =).
I thought there would be a straightforward way to do this via Xlib or xcb (xpyb) but in my experiments the best I've been able to do is detect when a window is created, destroyed, or moved. That's great and all but I need to know when the contents of windows change as well (imagine sending a keystroke to an xterm and having it appear frozen until you move the window).
If someone knows of a way to tell when the contents of an X11 window have changed I'd love to hear it! I'm open to creative solutions. For example, I tried using ffmpeg to stream x11grab through a fifo with regular checks to see if anything changed but it turned out to be extremely inefficient in terms of CPU utilization (it also seems to slow the whole system down even if nothing is going on).
I also tried just grabbing 15fps worth of screenshots in a loop while checking for changes in the most efficient way I could (e.g. does this cStringIO buffer match the last one?). That also was very CPU intensive.
The ideal solution would be for me to be able to watch the file descriptor of a socket and call a handler when there's a change in the X11 window. I'm willing to settle for detecting when the whole X11 screen has a change... That'd still be better than what I've got.
Any and all help with this is appreciated!
First of all, you can actually use vnc to track changes in just one window, not whole desktop. From x11vnc documentation:
-id windowid Show the X window corresponding to "windowid" not
the entire display. New windows like popup menus,
transient toplevels, etc, may not be seen or may be
clipped. Disabling SaveUnders or BackingStore in the
X server may help show them. x11vnc may crash if the
window is initially partially obscured, changes size,
is iconified, etc. Some steps are taken to avoid this
and the -xrandr mechanism is used to track resizes. Use
xwininfo(1) to get the window id, or use "-id pick"
to have x11vnc run xwininfo(1) for you and extract
the id. The -id option is useful for exporting very
simple applications (e.g. the current view on a webcam).
-sid windowid As -id, but instead of using the window directly it
shifts a root view to it: this shows SaveUnders menus,
etc, although they will be clipped if they extend beyond
the window.
-appshare Simple application sharing based on the -id/-sid
mechanism. Every new toplevel window that the
application creates induces a new viewer window via
a reverse connection. The -id/-sid and -connect
options are required. Run 'x11vnc -appshare -help'
for more info.
If you want to code similar functionality manually you need to use damage extension.
Here is simple example in javascript using node-x11 (sorry, I'm not sure about damage extension support in python)
var x11 = require('x11');
var X = x11.createClient(function(err, display) {
X.require('damage', function(Damage) {
var damage = X.AllocID();
Damage.Create(damage, parseInt(process.argv[2]), Damage.ReportLevel.NonEmpty);
X.on('event', function(ev) {
Damage.Subtract(damage, 0, 0);
console.log("window content changed!");
});
});
});
start it with window id as command line argument and you'll be notified whenever window content is changed.