[Bugs] #342 UNSP: sugar-emulator: some keys (e.g. cursor keys) not working

SugarLabs Bugs bugtracker-noreply at sugarlabs.org
Thu Jun 25 10:08:34 EDT 2009


#342: sugar-emulator: some keys (e.g. cursor keys) not working
------------------------------------------+---------------------------------
    Reporter:  sascha_silbe               |          Owner:  sascha_silbe               
        Type:  defect                     |         Status:  assigned                   
    Priority:  Unspecified by Maintainer  |      Milestone:  Unspecified by Release Team
   Component:  sugar-jhbuild              |        Version:  Git as of bugdate          
    Severity:  Major                      |     Resolution:                             
    Keywords:                             |   Distribution:  Unspecified                
Status_field:  New                        |  
------------------------------------------+---------------------------------

Comment(by DanKrejsa):

 (Until this is fixed upstream, the following may be relevant)
 Hi,

 I've found what I think is a better workaround for the Xephyr problem seen
 running sugar-emulator, in which keyboard mappings are not inherited from
 the main X server.

 One workaround known so far is to go into the Terminal activity
 and run

   setxkbmap us

 (or whatever keyboard map & options you want).  However, that doesn't fix
 all keys, in particular it doesn't fix the arrow keys (at least for me).
 What does
 work is to execute, in a host shell outside of the sugar emulator,

   xkbcomp $DISPLAY :100

 replacing :100 with the actual X display of the Xephyr X server;
 $DISPLAY is of course the name of the encompassing X display in
 which Xephyr runs as a client.   This copies the XKB settings from
 the encompassing display to the display under Xephyr.

 You have to run xkbcomp after having sent some keyboard events
 to Xephyr -- if you do it before that, it seems not to work for some
 reason
 that I don't understand well.

 That leads me to a really hackish patch to:

   sugar-jhbuild/source/sugar/bin/sugar-emulator

 adding a -k option that does the xkbcomp to copy the XKB settings to
 Xephyr before starting sugar.  The most awkward bit is that I had to
 add code to put an ugly little window in the Xephyr server waiting for an
 initial keystroke before calling xkbcomp.  I know very little about X;
 maybe
 someone can figure out how to avoid that bit.

 If you use the patch, start sugar-emulator as follows:

  $ ./sugar-jhbuild run sugar-emulator -k &

 Briefly tested only under Fedora 11. Enjoy,

 {{{
 diff --git a/bin/sugar-emulator b/bin/sugar-emulator
 index acd5976..dfe2230 100644
 --- a/bin/sugar-emulator
 +++ b/bin/sugar-emulator
 @@ -24,13 +24,43 @@ from optparse import OptionParser
  import gtk
  import gobject

 +import sys
 +
  from sugar import env

 +class WaitForKey:
 +    def destroy(self, widget, data=None):
 +        gtk.main_quit()
 +
 +    def __init__(self, dst_display):
 +        display = gtk.gdk.Display(dst_display)
 +        screen = display.get_default_screen()
 +        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
 +        self.window = window
 +        self.display = display
 +        self.screen = screen
 +        window.set_screen(screen)
 +        # No window manager yet...
 +        window.set_geometry_hints(None, 600, 450)
 +        window.connect("destroy", self.destroy)
 +        window.connect("key-release-event", self.destroy)
 +        vbox = gtk.VBox()
 +        entry = gtk.Entry()
 +        entry.set_text ("Type a key here!")
 +        window.add(vbox)
 +        vbox.pack_start(entry, True, True)
 +        entry.show()
 +        vbox.show()
 +        window.show()
 +
 +    def main(self):
 +        gtk.main()
 +
  default_dimensions = (800, 600)
 -def _run_xephyr(display, dpi, dimensions, fullscreen):
 +def _run_xephyr(display, dpi, dimensions, fullscreen, noreset = False):
      cmd = [ 'Xephyr' ]
      cmd.append(':%d' % display)
 -    cmd.append('-ac')
 +    cmd.append('-ac')

      screen_size = (gtk.gdk.screen_width(), gtk.gdk.screen_height())

 @@ -57,6 +87,9 @@ def _run_xephyr(display, dpi, dimensions, fullscreen):
          cmd.append('-dpi')
          cmd.append('%d' % dpi)

 +    if noreset :
 +        cmd.append('-noreset')
 +
      result = gobject.spawn_async(cmd, flags=gobject.SPAWN_SEARCH_PATH)
      pid = result[0]

 @@ -69,20 +102,39 @@ def _check_xephyr(display):
                               stderr=open(os.devnull, "w"))
      return result == 0

 -def _start_xephyr(dpi, dimensions, fullscreen):
 +def _copy_xkb(src_display, dst_display):
 +    wfk = WaitForKey(dst_display)
 +    wfk.main()
 +    result = subprocess.call(['xkbcomp', src_display, dst_display])
 +    print >> sys.stderr, "'xkbcomp %s %s' returned %d" % \
 +           (src_display, dst_display, result)
 +
 +def _start_xephyr(dpi, dimensions, fullscreen, copy_xkb = False):
 +
 +    try:
 +        old_display = os.environ['DISPLAY']
 +    except KeyError:
 +        options.copy_xkb = False
 +
      # FIXME evil workaround until F10 Xephyr is fixed
      if os.path.exists('/etc/fedora-release'):
          if open('/etc/fedora-release').read().startswith('Fedora release
 10'):
 -            _run_xephyr(random.randint(100, 500), dpi, dimensions,
 fullscreen)
 +            _run_xephyr(random.randint(100, 500),
 +                        dpi, dimensions, fullscreen, copy_xkb)
 +            if copy_xkb:
 +                time.sleep(1.0)
 +                _copy_xkb (old_display, os.environ['DISPLAY'])
              return

      for display in range(100, 110):
          if not _check_xephyr(display):
 -            _run_xephyr(display, dpi, dimensions, fullscreen)
 +            _run_xephyr(display, dpi, dimensions, fullscreen, copy_xkb)

              tries = 10
              while tries > 0:
                  if _check_xephyr(display):
 +                    if (copy_xkb):
 +                        _copy_xkb (old_display, os.environ['DISPLAY'])
                      return
                  else:
                      tries -= 1
 @@ -143,11 +195,17 @@ def main():
      parser.add_option('-F', '--no-fullscreen', dest='fullscreen',
                        action='store_false',
                        help='Do not run emulator in fullscreen mode')
 +    parser.add_option('-k', '--copy-xkb', dest='copy_xkb',
 +                      action='store_true', default=False,
 +                      help='Copy XKB settings from X server to Xephyr')
      (options, args) = parser.parse_args()

      _setup_env()

 -    _start_xephyr(options.dpi, options.dimensions, options.fullscreen)
 +    _start_xephyr(options.dpi,
 +                  options.dimensions,
 +                  options.fullscreen,
 +                  options.copy_xkb)

      if options.scaling:
          os.environ['SUGAR_SCALING'] = options.scaling
 }}}

-- 
Ticket URL: <http://dev.sugarlabs.org/ticket/342#comment:7>
Sugar Labs <http://sugarlabs.org/>
Sugar Labs bug tracking system


More information about the Bugs mailing list