Glade Panel in Axis blocks arrow keys

More
5 years 3 weeks ago - 5 years 3 weeks ago #222463 by +Jan+
Replied by +Jan+ on topic Glade Panel in Axis blocks arrow keys
Hello,
three years later, I am facing the same problem again. I have a new machine which I run with Linuxcnc 2.8.2.
The Glade panel is still the same, and I use the XEMBED.py file we created for LinuxCNC 2.8 Master back then.
That's how the machine behaves:


- Pushing the arrow key for x+ or x- , moving the mouse into the glade panel and then releasing the arrow key ==> release not detected
- Moving than with the mouse out of the glade panel and hitting the arrow key once again ==> release detected and machine stops
- Pushing x+ or x- arrow key, moving the mouse into the glade panel and then releasing the arrow key ==> RELEASE DETECTED!
- Then pushing the arrow key y+ or y-, moving the mouse into the glade panel and releasing the arrow key ==> release not detected
- Moving than with the mouse out of the glade panel and hitting the arrow key once again ==> release detected and machine stops
- Pushing y+ or y- arrow key, moving the mouse into the glade panel and then releasing the arrow key ==> RELEASE DETECTED!
- But then the release of x+ and x- is not detected anymore... and so on...
I have again created a video with key logging and open terminal for debugging:



Here is the code of the Xembed file:
Code:
#!/usr/bin/env python # vim: sts=4 sw=4 et """ XEmbed helper functions to allow correct embeding inside Axis """ import gtk import linuxcnc CMD = linuxcnc.command() def reparent(window, parent):     """ Forced reparent. When reparenting Gtk applications into Tk     some extra protocol calls are needed.     """     from Xlib import display     from Xlib.xobject import drawable     if not parent:         return window     plug = gtk.Plug(long(parent))     plug.show()     d = display.Display()     w = drawable.Window(d.display, plug.window.xid, 0)     # Honor XEmbed spec     atom = d.get_atom('_XEMBED_INFO')     w.change_property(atom, atom, 32, [0, 1])     w.reparent(parent, 0, 0)     w.map()     d.sync()     for c in window.get_children():         window.remove(c)         plug.add(c)     # Hide window if it's displayed     window.unmap()     return plug def keyboard_forward(window, forward):     """ XXX: Keyboard events forwardind         This is kind of hack needed to properly function inside Tk windows.         Gtk app will receive _all_ events, even not needed. So we have to forward         back things that left over after our widgets. Connect handlers _after_         all others and listen for key-presss and key-release events. If key is not         in ignore list - forward it to window id found in evironment.     """     if not forward:         return     try:         forward = int(forward, 0)     except:         return     from Xlib.protocol import event     from Xlib import display, X     from Xlib.xobject import drawable     d = display.Display()     fw = drawable.Window(d.display, forward, 0)     ks = gtk.keysyms     ignore = [ ks.Tab, ks.Page_Up, ks.Page_Down              , ks.KP_Page_Up, ks.KP_Page_Down              , ks.Left, ks.Right, ks.Up, ks.Down              , ks.KP_Left, ks.KP_Right, ks.KP_Up, ks.KP_Down              , ks.bracketleft, ks.bracketright              ]     def gtk2xlib(e, fw, g, type=None):         if type is None: type = e.type         if type == gtk.gdk.KEY_PRESS:             klass = event.KeyPress         elif type == gtk.gdk.KEY_RELEASE:             klass = event.KeyRelease         else:             return         kw = dict(window=fw, detail=e.hardware_keycode,                   state=e.state & 0xff,                   child=X.NONE, root=g._data['root'],                   root_x=g._data['x'], root_y=g._data['y'],                   event_x=0, event_y=0, same_screen=1)         return klass(time=e.time, **kw)     def forward_press(w, e, fw):         if e.keyval in ignore:             return         g = fw.get_geometry()         fe = gtk2xlib(e, fw, g)         if not fe: return         fw.send_event(fe)     def forward_release(w, e, fw):         if e.keyval in ignore:             CMD.jog(linuxcnc.JOG_STOP, 1,0)             print 'stop0'             CMD.jog(linuxcnc.JOG_STOP, 1,1)             print 'stop1'             CMD.jog(linuxcnc.JOG_STOP, 1,2)             print 'stop2'             g = fw.get_geometry()             fe = gtk2xlib(e, fw, g)             if not fe: return         g = fw.get_geometry()         fe = gtk2xlib(e, fw, g)         if not fe: return         fw.send_event(fe)     window.connect_after("key-press-event", forward_press, fw)     window.connect("key-release-event", forward_release, fw)     window.add_events(gtk.gdk.KEY_PRESS_MASK)     window.add_events(gtk.gdk.KEY_RELEASE_MASK)

Where could be the error?

Thanks in advance

Jan
 
Last edit: 5 years 3 weeks ago by +Jan+. Reason: format issues...

Please Log in or Create an account to join the conversation.

More
5 years 3 weeks ago #222767 by nkp
Replied by nkp on topic Glade Panel in Axis blocks arrow keys
And if you turn off the keyboard arrows, and instead draw buttons on the panel
Warning: Spoiler!

Please Log in or Create an account to join the conversation.

More
5 years 3 weeks ago #222792 by +Jan+
Replied by +Jan+ on topic Glade Panel in Axis blocks arrow keys
That would be a workaround, but not a good one. The machine is too big:

 

I need hardware keys which I can use without looking on them ;-) 
The next step is then to put the electronic handwheel from the scrap back into operation.

 

Until then, however, I would like to keep the cursor keys. Do you have the same problem when using the hardware arrow keys?

Best wishes

Jan

Please Log in or Create an account to join the conversation.

More
5 years 2 weeks ago #222983 by andypugh
Replied by andypugh on topic Glade Panel in Axis blocks arrow keys
I think that the old pendant looks like too much work.

So, consider buying one of the XHC-type pendants that LinuxCNC already supports.

linuxcnc.org/docs/2.8/html/man/man1/xhc-whb04b-6.1.html

Please Log in or Create an account to join the conversation.

More
5 years 2 weeks ago #222992 by rodw
Replied by rodw on topic Glade Panel in Axis blocks arrow keys
If its a standard MPG encoder and the axis selection and scales are hardwired , its quite easy to wire it into a Mesa MPG input (eg on 776e).
I use a 433Mhz wireless pendant with a receiver box that is all hardwired into a Mesa 7i76e. There is a MPG example in the docs which will guide you. I use binary coded inputs that output a logical bitmap which I decode to save a few pins.

Please Log in or Create an account to join the conversation.

More
5 years 2 weeks ago - 5 years 2 weeks ago #223069 by +Jan+
Replied by +Jan+ on topic Glade Panel in Axis blocks arrow keys
I love to give things from the scrap a second use. The handwheel is built like a tank and actually too good to throw away. It is a normal encoder and rotary switches without any electronics installed. I will try to put it into operation, but if I can't I will gladly fall back on the XHC variant.

I have now test updated to Linux MX and Master 2.9. Also here I have with e.g. the GladeVCP example from PNCCONF the same dangerous behavior. Does no one but me use Axis with a Glade side panel and arrow keys? The Xembed file (see attachment) looks different in Master, but I don't know where to start to solve the problem.
Code:
#!/usr/bin/env python3 # vim: sts=4 sw=4 et """ XEmbed helper functions to allow correct embeding inside Axis """ import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk from gi.repository import Gdk def reparent(window, parent):     """ Forced reparent. When reparenting Gtk applications into Tk     some extra protocol calls are needed.     """     from Xlib import display     from Xlib.xobject import drawable     if not parent:         return window     plug = Gtk.Plug.new(int(parent))     plug.show_all()     d = display.Display()     w = drawable.Window(d.display, plug.get_window().get_xid(), 0)     # Honor XEmbed spec     atom = d.get_atom('_XEMBED_INFO')     w.change_property(atom, atom, 32, [0, 1])     w.reparent(parent, 0, 0)     w.map()     d.sync()     for c in window.get_children():         window.remove(c)         plug.add(c)     # Hide window if it's displayed     window.unmap()     return plug def add_plug(window):     """Replace top level with a plug so it can be reparented.     This doesn't actually reparent the widget     """     plug = Gtk.Plug(0)     plug.show()     for c in window.get_children():         window.remove(c)         plug.add(c)     # Hide window if it's displayed     window.unmap()     return plug def keyboard_forward(window, forward):     """ XXX: Keyboard events forwardind         This is kind of hack needed to properly function inside Tk windows.         Gtk app will receive _all_ events, even not needed. So we have to forward         back things that left over after our widgets. Connect handlers _after_         all others and listen for key-press and key-release events. If key is not         in ignore list - forward it to window id found in environment.     """     if not forward:         return     try:         forward = int(forward, 0)     except:         return     from Xlib.protocol import event     from Xlib import display, X     from Xlib.xobject import drawable     d = display.Display()     fw = drawable.Window(d.display, forward, 0) #TODO: GTK3 #    ks = gtk.keysyms     ignore = #[ ks.Tab, ks.Page_Up, ks.Page_Down #             , ks.KP_Page_Up, ks.KP_Page_Down #             , ks.Left, ks.Right, ks.Up, ks.Down #             , ks.KP_Left, ks.KP_Right, ks.KP_Up, ks.KP_Down #             , ks.bracketleft, ks.bracketright #             ]     def gtk2xlib(e, fw, g, type=None):         if type is None: type = e.type         if type == Gdk.EventType.KEY_PRESS:             klass = event.KeyPress         elif type == Gdk.EventType.KEY_RELEASE:             klass = event.KeyRelease         else:             return         kw = dict(window=fw, detail=e.hardware_keycode,                   state=e.state & 0xff,                   child=X.NONE, root=g._data['root'],                   root_x=g._data['x'], root_y=g._data['y'],                   event_x=0, event_y=0, same_screen=1)         return klass(time=e.time, **kw)     def forward(w, e, fw):         if e.keyval in ignore:             return         g = fw.get_geometry()         fe = gtk2xlib(e, fw, g)         if not fe: return         fw.send_event(fe)     window.connect_after("key-press-event", forward, fw)     window.connect("key-release-event", forward, fw)     #TODO:     #window.add_events(Gdk.EventType.KEY_PRESS_MASK)     #window.add_events(Gdk.EventType.KEY_RELEASE_MASK)

Does anyone have an idea?

Best wishes

Jan
Last edit: 5 years 2 weeks ago by +Jan+.

Please Log in or Create an account to join the conversation.

Time to create page: 0.211 seconds
Powered by Kunena Forum