def make_layoutsmenuitem(self):
        keyboard = self.menuitem("Keyboard", "keyboard.png",
                                 "Select your keyboard layout", None)
        keyboard.set_sensitive(False)
        self.layout_submenu = gtk.Menu()
        keyboard.set_submenu(self.layout_submenu)
        self.popup_menu_workaround(self.layout_submenu)

        def kbitem(title, layout, variant):
            def set_layout(item):
                """ this callback updates the client (and server) if needed """
                item = ensure_item_selected(self.layout_submenu, item)
                layout = item.keyboard_layout
                variant = item.keyboard_variant
                if layout != self.client.xkbmap_layout or variant != self.client.xkbmap_variant:
                    log("keyboard layout selected: %s / %s", layout, variant)
                    self.client.xkbmap_layout = layout
                    self.client.xkbmap_variant = variant
                    self.client.send_layout()

            l = self.checkitem(title, set_layout)
            l.set_draw_as_radio(True)
            l.keyboard_layout = layout
            l.keyboard_variant = variant
            return l

        def keysort(key):
            c, l = key
            return c.lower() + l.lower()

        layout, variant, variants = self.client.keyboard_helper.keyboard.get_layout_spec(
        )
        if layout and len(variants) > 1:
            #just show all the variants to choose from this layout
            self.layout_submenu.append(
                kbitem("%s - Default" % layout, layout, None))
            for v in variants:
                self.layout_submenu.append(
                    kbitem("%s - %s" % (layout, v), layout, v))
        else:
            from xpra.keyboard.layouts import X11_LAYOUTS
            #show all options to choose from:
            sorted_keys = list(X11_LAYOUTS.keys())
            sorted_keys.sort(key=keysort)
            for key in sorted_keys:
                country, language = key
                layout, variants = X11_LAYOUTS.get(key)
                name = "%s - %s" % (country, language)
                if len(variants) > 1:
                    #sub-menu for each variant:
                    variant = self.menuitem(name, tooltip=layout)
                    variant_submenu = gtk.Menu()
                    variant.set_submenu(variant_submenu)
                    self.popup_menu_workaround(variant_submenu)
                    self.layout_submenu.append(variant)
                    variant_submenu.append(
                        kbitem("%s - Default" % layout, layout, None))
                    for v in variants:
                        variant_submenu.append(
                            kbitem("%s - %s" % (layout, v), layout, v))
                else:
                    #no variants:
                    self.layout_submenu.append(kbitem(name, layout, None))
        keyboard_helper = self.client.keyboard_helper

        def set_selected_layout(*args):
            if keyboard_helper.xkbmap_layout or keyboard_helper.xkbmap_print or keyboard_helper.xkbmap_query:
                #we have detected a layout
                #so no need to let the user override it
                keyboard.hide()
                return
            keyboard.set_sensitive(True)
            layout = keyboard_helper.xkbmap_layout
            variant = keyboard_helper.xkbmap_variant

            def is_match(checkitem):
                return checkitem.keyboard_layout == layout and checkitem.keyboard_variant == variant

            set_checkeditems(self.layout_submenu, is_match)

        self.client.connect("handshake-complete", set_selected_layout)
        return keyboard
    def make_layoutsmenuitem(self):
        keyboard = self.menuitem("Keyboard", "keyboard.png",
                                 "Select your keyboard layout", None)
        set_sensitive(keyboard, False)
        self.layout_submenu = gtk.Menu()
        keyboard.set_submenu(self.layout_submenu)
        self.popup_menu_workaround(self.layout_submenu)

        def kbitem(title, layout, variant, active=False):
            def set_layout(item):
                """ this callback updates the client (and server) if needed """
                ensure_item_selected(self.layout_submenu, item)
                layout = item.keyboard_layout
                variant = item.keyboard_variant
                kh = self.client.keyboard_helper
                kh.locked = layout != "Auto"
                if layout != kh.xkbmap_layout or variant != kh.xkbmap_variant:
                    if layout == "Auto":
                        #re-detect everything:
                        kh.update()
                        log.info("keyboard automatic mode: %s",
                                 kh.layout_str())
                        kh.send_layout()
                        kh.send_keymap()
                    else:
                        #use layout specified and send it:
                        kh.xkbmap_layout = layout
                        kh.xkbmap_variant = variant
                        log.info("new keyboard layout selected: %s",
                                 kh.layout_str())
                        kh.send_layout()

            l = self.checkitem(title, set_layout, active)
            l.set_draw_as_radio(True)
            l.keyboard_layout = layout
            l.keyboard_variant = variant
            return l

        def keysort(key):
            c, l = key
            return c.lower() + l.lower()

        layout, layouts, variant, variants = self.client.keyboard_helper.keyboard.get_layout_spec(
        )
        full_layout_list = False
        if len(layouts) > 1:
            log.info("keyboard layouts: %s", ",".join(layouts))
            auto = kbitem("Auto", "Auto", "", True)
            self.layout_submenu.append(auto)
            if layout:
                self.layout_submenu.append(kbitem("%s" % layout, layout, ""))
            if variants:
                for v in variants:
                    self.layout_submenu.append(
                        kbitem("%s - %s" % (layout, v), layout, v))
            for l in layouts:
                if l != layout:
                    self.layout_submenu.append(kbitem("%s" % l, l, ""))
        elif layout and variants and len(variants) > 1:
            #just show all the variants to choose from this layout
            default = kbitem("%s - Default" % layout, layout, "", True)
            self.layout_submenu.append(default)
            for v in variants:
                self.layout_submenu.append(
                    kbitem("%s - %s" % (layout, v), layout, v))
        else:
            full_layout_list = True
            from xpra.keyboard.layouts import X11_LAYOUTS
            #show all options to choose from:
            sorted_keys = list(X11_LAYOUTS.keys())
            sorted_keys.sort(key=keysort)
            for key in sorted_keys:
                country, language = key
                layout, variants = X11_LAYOUTS.get(key)
                name = "%s - %s" % (country, language)
                if len(variants) > 1:
                    #sub-menu for each variant:
                    variant = self.menuitem(name, tooltip=layout)
                    variant_submenu = gtk.Menu()
                    variant.set_submenu(variant_submenu)
                    self.popup_menu_workaround(variant_submenu)
                    self.layout_submenu.append(variant)
                    variant_submenu.append(
                        kbitem("%s - Default" % layout, layout, None))
                    for v in variants:
                        variant_submenu.append(
                            kbitem("%s - %s" % (layout, v), layout, v))
                else:
                    #no variants:
                    self.layout_submenu.append(kbitem(name, layout, None))
        keyboard_helper = self.client.keyboard_helper

        def set_layout_enabled(*args):
            if full_layout_list and (keyboard_helper.xkbmap_layout
                                     or keyboard_helper.xkbmap_print
                                     or keyboard_helper.xkbmap_query):
                #we have detected a layout
                #so no need to show the user the huge layout list
                keyboard.hide()
                return
            set_sensitive(keyboard, True)

        self.client.connect("handshake-complete", set_layout_enabled)
        return keyboard
 def make_layoutsmenuitem(self):
     keyboard = self.menuitem("Keyboard", "keyboard.png", "Select your keyboard layout", None)
     keyboard.set_sensitive(False)
     self.layout_submenu = gtk.Menu()
     keyboard.set_submenu(self.layout_submenu)
     self.popup_menu_workaround(self.layout_submenu)
     def kbitem(title, layout, variant):
         def set_layout(item):
             """ this callback updates the client (and server) if needed """
             item = ensure_item_selected(self.layout_submenu, item)
             layout = item.keyboard_layout
             variant = item.keyboard_variant
             if layout!=self.client.xkbmap_layout or variant!=self.client.xkbmap_variant:
                 debug("keyboard layout selected: %s / %s", layout, variant)
                 self.client.xkbmap_layout = layout
                 self.client.xkbmap_variant = variant
                 self.client.send_layout()
         l = self.checkitem(title, set_layout)
         l.set_draw_as_radio(True)
         l.keyboard_layout = layout
         l.keyboard_variant = variant
         return l
     def keysort(key):
         c,l = key
         return c.lower()+l.lower()
     layout,variant,variants = self.client.keyboard_helper.keyboard.get_layout_spec()
     if layout and len(variants)>1:
         #just show all the variants to choose from this layout
         self.layout_submenu.append(kbitem("%s - Default" % layout, layout, None))
         for v in variants:
             self.layout_submenu.append(kbitem("%s - %s" % (layout, v), layout, v))
     else:
         from xpra.keyboard.layouts import X11_LAYOUTS
         #show all options to choose from:
         sorted_keys = list(X11_LAYOUTS.keys())
         sorted_keys.sort(key=keysort)
         for key in sorted_keys:
             country,language = key
             layout,variants = X11_LAYOUTS.get(key)
             name = "%s - %s" % (country, language)
             if len(variants)>1:
                 #sub-menu for each variant:
                 variant = self.menuitem(name, tooltip=layout)
                 variant_submenu = gtk.Menu()
                 variant.set_submenu(variant_submenu)
                 self.popup_menu_workaround(variant_submenu)
                 self.layout_submenu.append(variant)
                 variant_submenu.append(kbitem("%s - Default" % layout, layout, None))
                 for v in variants:
                     variant_submenu.append(kbitem("%s - %s" % (layout, v), layout, v))
             else:
                 #no variants:
                 self.layout_submenu.append(kbitem(name, layout, None))
     keyboard_helper = self.client.keyboard_helper
     def set_selected_layout(*args):
         if keyboard_helper.xkbmap_layout or keyboard_helper.xkbmap_print or keyboard_helper.xkbmap_query:
             #we have detected a layout
             #so no need to let the user override it
             keyboard.hide()
             return
         keyboard.set_sensitive(True)
         layout = keyboard_helper.xkbmap_layout
         variant = keyboard_helper.xkbmap_variant
         def is_match(checkitem):
             return checkitem.keyboard_layout==layout and checkitem.keyboard_variant==variant
         set_checkeditems(self.layout_submenu, is_match)
     self.client.connect("handshake-complete", set_selected_layout)
     return keyboard
 def make_layoutsmenuitem(self):
     keyboard = self.menuitem("Keyboard", "keyboard.png", "Select your keyboard layout", None)
     set_sensitive(keyboard, False)
     self.layout_submenu = gtk.Menu()
     keyboard.set_submenu(self.layout_submenu)
     self.popup_menu_workaround(self.layout_submenu)
     def kbitem(title, layout, variant, active=False):
         def set_layout(item):
             """ this callback updates the client (and server) if needed """
             ensure_item_selected(self.layout_submenu, item)
             layout = item.keyboard_layout
             variant = item.keyboard_variant
             kh = self.client.keyboard_helper
             kh.locked = layout!="Auto"
             if layout!=kh.xkbmap_layout or variant!=kh.xkbmap_variant:
                 if layout=="Auto":
                     #re-detect everything:
                     kh.update()
                     log.info("keyboard automatic mode: %s", kh.layout_str())
                     kh.send_layout()
                     kh.send_keymap()
                 else:
                     #use layout specified and send it:
                     kh.xkbmap_layout = layout
                     kh.xkbmap_variant = variant
                     log.info("new keyboard layout selected: %s", kh.layout_str())
                     kh.send_layout()
         l = self.checkitem(title, set_layout, active)
         l.set_draw_as_radio(True)
         l.keyboard_layout = layout
         l.keyboard_variant = variant
         return l
     def keysort(key):
         c,l = key
         return c.lower()+l.lower()
     layout,layouts,variant,variants = self.client.keyboard_helper.keyboard.get_layout_spec()
     full_layout_list = False
     if len(layouts)>1:
         log("keyboard layouts: %s", u",".join(bytestostr(x) for x in layouts))
         #log after removing dupes:
         def uniq(seq):
             seen = set()
             return [x for x in seq if not (x in seen or seen.add(x))]
         log.info("keyboard layouts: %s", u",".join(bytestostr(x) for x in uniq(layouts)))
         auto = kbitem("Auto", "Auto", "", True)
         self.layout_submenu.append(auto)
         if layout:
             self.layout_submenu.append(kbitem("%s" % layout, layout, ""))
         if variants:
             for v in variants:
                 self.layout_submenu.append(kbitem("%s - %s" % (layout, v), layout, v))
         for l in uniq(layouts):
             if l!=layout:
                 self.layout_submenu.append(kbitem("%s" % l, l, ""))
     elif layout and variants and len(variants)>1:
         #just show all the variants to choose from this layout
         default = kbitem("%s - Default" % layout, layout, "", True)
         self.layout_submenu.append(default)
         for v in variants:
             self.layout_submenu.append(kbitem("%s - %s" % (layout, v), layout, v))
     else:
         full_layout_list = True
         from xpra.keyboard.layouts import X11_LAYOUTS
         #show all options to choose from:
         sorted_keys = list(X11_LAYOUTS.keys())
         sorted_keys.sort(key=keysort)
         for key in sorted_keys:
             country,language = key
             layout,variants = X11_LAYOUTS.get(key)
             name = "%s - %s" % (country, language)
             if len(variants)>1:
                 #sub-menu for each variant:
                 variant = self.menuitem(name, tooltip=layout)
                 variant_submenu = gtk.Menu()
                 variant.set_submenu(variant_submenu)
                 self.popup_menu_workaround(variant_submenu)
                 self.layout_submenu.append(variant)
                 variant_submenu.append(kbitem("%s - Default" % layout, layout, None))
                 for v in variants:
                     variant_submenu.append(kbitem("%s - %s" % (layout, v), layout, v))
             else:
                 #no variants:
                 self.layout_submenu.append(kbitem(name, layout, None))
     keyboard_helper = self.client.keyboard_helper
     def set_layout_enabled(*args):
         if full_layout_list and (keyboard_helper.xkbmap_layout or keyboard_helper.xkbmap_print or keyboard_helper.xkbmap_query):
             #we have detected a layout
             #so no need to show the user the huge layout list
             keyboard.hide()
             return
         set_sensitive(keyboard, True)
     self.client.after_handshake(set_layout_enabled)
     return keyboard