omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    can pykeys see key presses from external keyboards?

    Pythonista
    6
    29
    10542
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • cvp
      cvp @jamm last edited by

      @jamm As @JonB asked, do you want to write a custom keyboard for another app than Pythonista? As your code uses keyboard module, we could believe it.
      If you only want to intercept a keyboard key in a Pythonista app, in a TextView, then @mikael advice is ok.

      1 Reply Last reply Reply Quote 0
      • jamm
        jamm last edited by

        In another app I want it to form tags around the text every time enter is pressed. It seems impossible due to limitations.

        cvp 2 Replies Last reply Reply Quote 0
        • cvp
          cvp @jamm last edited by cvp

          @jamm I don't know with an external keyboard because I don't have it for testing but, with the virtual keyboard, I think it is possible, but I may be wrong

          1 Reply Last reply Reply Quote 0
          • cvp
            cvp @jamm last edited by cvp

            @jamm please try this quick and dirty script as custom keyboard in any app.
            You will see automatic insert of BEF at begin and END at end of line where you tap return.

            #!python3
            import keyboard
            import ui
            
            class KeyboardInfoView (ui.View):
            	def __init__(self, *args, **kwargs):
            		super().__init__(self, *args, **kwargs)
            		self.background_color = '#00436e'
            		
            	def kb_should_insert(self, text):
            		# You can modify the inserted text here:
            		if ord(text) == 10:	# return key pressed
            			before,after = keyboard.get_input_context()
            			keyboard.backspace(len(before))
            			keyboard.insert_text('BEF'+before+'END')
            		return text
            
            if __name__ == '__main__':
            	v = KeyboardInfoView()
            	keyboard.set_view(v, mode='minimized')
            

            1 Reply Last reply Reply Quote 0
            • cvp
              cvp last edited by

              Code is not fully ok.
              In some apps, the "before" part of context is the entire line, in other apps, no.
              Thus, code must be improved. Take it as first draft.

              1 Reply Last reply Reply Quote 0
              • cvp
                cvp last edited by cvp

                A little bit better, no backspace, but still only ok if "before" = entire line before cursor

                #!python3
                import keyboard
                import ui
                
                class KeyboardInfoView (ui.View):
                	def __init__(self, *args, **kwargs):
                		super().__init__(self, *args, **kwargs)
                		self.background_color = '#00436e'
                		
                	def kb_should_insert(self, text):
                		# You can modify the inserted text here:
                		if ord(text) == 10:	# return key pressed
                			before,after = keyboard.get_input_context()
                			# hoping that before = entire line before cursor
                			keyboard.move_cursor(-len(before))
                			keyboard.insert_text('BEF')
                			keyboard.move_cursor(len(before))
                			keyboard.insert_text('END')
                			#keyboard.backspace(len(before))
                			#keyboard.insert_text('BEF'+before+'END')
                		return text
                
                if __name__ == '__main__':
                	v = KeyboardInfoView()
                	keyboard.set_view(v, mode='minimized') 
                
                1 Reply Last reply Reply Quote 0
                • mcriley821
                  mcriley821 last edited by

                  Might be worth checking into key commands

                  http://omz-software.com/pythonista/docs/ios/ui.html#ui.View.key_command

                  cvp 1 Reply Last reply Reply Quote 0
                  • cvp
                    cvp @mcriley821 last edited by

                    @mcriley821 key_command is not called in this case and, anyway, does not allow to modify entry, and surely not in an other app than Pythonista

                    1 Reply Last reply Reply Quote 0
                    • trey
                      trey last edited by trey

                      I was interested in this same question and created a forum account intending to ask it when I saw this thread already active.

                      So, I just tried the “BEF END” test script above (the latter one, “A little bit better), and it works as advertised in some programs (such as the Pythonista editor itself) when you tap “return” on the onscreen keyboard, except for one thing—it makes the text view jump down so that the typed text is offscreen.

                      In other apps (such as typing into this very text field in the forum using Safari), it only partially works with the software keyboard—it inserts BEF, but never END.

                      But with an external keyboard, it does absolutely nothing that I can see. Well, it does do one thing: my standard layout is Dvorak, but switching to Pythonista keyboard, the HW keyboard becomes QWERTY again.

                      I tried the key_command mentioned, too, and it is never called.

                      Btw, the problem I was hoping to solve was a multilingual keyboard—using switchable input methods like Vim and Emacs offer, or RFC 1345 encoding, letting me type multilingual text without having to learn the native keyboard layouts for each script.

                      cvp JonB 6 Replies Last reply Reply Quote 0
                      • cvp
                        cvp @trey last edited by

                        @trey said:

                        —it makes the text view jump down so that the typed text is offscreen.

                        I don't have this problem, but don't forget that my little script was only written to show what could be possible, sure it is not bug free 🙄

                        1 Reply Last reply Reply Quote 0
                        • cvp
                          cvp @trey last edited by

                          @trey said:

                          —it inserts BEF, but never END

                          You're right, it is a bug more

                          1 Reply Last reply Reply Quote 0
                          • cvp
                            cvp @trey last edited by

                            @trey said:

                            switching to Pythonista keyboard, the HW keyboard becomes QWERTY again.

                            Normal, Pythonista keyboard is always QWERTY

                            1 Reply Last reply Reply Quote 0
                            • cvp
                              cvp @trey last edited by

                              @trey said:

                              with an external keyboard, it does absolutely nothing that I can see.

                              I can't test anything, I don't have any external keyboard

                              trey 1 Reply Last reply Reply Quote 0
                              • cvp
                                cvp @trey last edited by

                                @trey said:

                                using switchable input methods

                                Could you give an example, please

                                1 Reply Last reply Reply Quote 0
                                • JonB
                                  JonB @trey last edited by

                                  Did the input_changed method get called at all?

                                  Honestly, it is not clear that the kb would get callbacks from an external keyboard -- i can't find anything in iOS docs that says it would. Since a kb extension is for converting user interaction into text, I can see reasons for not passing direct entry through a separate set of callbacks. Also, if the kb is not on screen, I'm not sure it is being called at all.

                                  trey 1 Reply Last reply Reply Quote 0
                                  • trey
                                    trey @JonB last edited by trey

                                    @JonB said:

                                    Did the input_changed method get called at all?

                                    No, not if I hid the onscreen keyboard. (At least, assuming playing a sound on each input_changed() call—which works with the software keyboard—should also work with the HW keyboard.) My bluetooth keyboard has a button to toggle it on and off, though the Apple keyboards do not have such a key. (I presume there’s a normal key combo I don’t know to do this, from the way other special keys work. Not the globe key—this toggle key on my keyboard, I believe, either tells iPadOS “show me the onscreen keyboard even with the Bluetooth keyboard active”, or it changes its HID/SPP presentation so it’s a secondary keyboard. I’m not sure.)

                                    But the crucial takeaway is that, even when the onscreen keyboard is visible and active, keypresses on the hardware keyboard do not trigger input_changed().

                                    The only reason I think there really should be some way to interact with the hardware keyboard is that, when you switch keyboards to Pythonista or any other third-party software keyboard, the hardware keyboard goes to plain QWERTY—when I have it set up via Settings (General → Keyboard → Hardware Keyboard) to do Dvorak. Yet, when I’m using the default Apple keyboard setup, the onscreen keyboard is QWERTY but the hw keyboard remains in Dvorak. Literally at this moment I type this, I have the Apple standard onscreen keyboard showing QWERTY, but I’m typing in Dvorak. (And if I do peck at the screen, the keys come out as shown in QWERTY, not Dvorak. I have it set up that way, you can make the the software keyboard Dvorak too, if you so choose.)

                                    Honestly, it is not clear that the kb would get callbacks from an external keyboard -- i can't find anything in iOS docs that says it would. Since a kb extension is for converting user interaction into text, I can see reasons for not passing direct entry through a separate set of callbacks. Also, if the kb is not on screen, I'm not sure it is being called at all.

                                    That would comport exactly with the behavior I’m seeing. That would really be disappointing. It would explain, though, why there are no hardware-kb-compatible keyboards on the App Store for things like unusual/custom keymaps or for languages Apple doesn’t directly support, like many Native American languages and Esperanto—if the OS doesn’t support it at all for App Store keyboards, Pythonista can’t do it either.

                                    1 Reply Last reply Reply Quote 0
                                    • trey
                                      trey @cvp last edited by trey

                                      @cvp said:

                                      @trey said:

                                      with an external keyboard, it does absolutely nothing that I can see.

                                      I can't test anything, I don't have any external keyboard

                                      You really don’t have access to a single Bluetooth keyboard, nor a “Camera connection” dongle whose USB port you can use to hook up your desktop USB keyboard? You don’t need a special iPad or iOS-compatible keyboard.

                                      I’m speed throttled from replying to your multiple messages, so I’ll reply here:

                                      Could you give an example, please

                                      I did give three examples, in the words immediately after the ones you copy-pasted—“like Vim or Emacs offer, or RFC 1345 encoding”.

                                      If you mean how would it work, in RFC1345 encoding you type some character to enter RFC1345 encoding—ampersand is common—and then you type a sequence of from one to three ASCII characters that mnemonically get you a character elsewhere in Unicode space. For instance, to type θ, you press &h*—all the Greek letters are the matching letter followed by asterisk, so capital Θ is typed &H*. There are no ambiguous subsequences, so when you finish you immediately get the character and can continue typing ASCII or another sequence starting &.

                                      It’s slow for typing full texts in other languages, but for cases like International Phonetic Alphabet, math notation, or programming languages that use non-ASCII unicode, it’s quite handy. Even things like typing characters that require the ⌥ key on Macs into ASCII-only inputs.

                                      cvp 1 Reply Last reply Reply Quote 1
                                      • JonB
                                        JonB last edited by

                                        Now, what you could maybe do is have a custom keyboard that has a built in textview -- then you can implement the textview delegate methods. You'd need a copy/paste button. (Actually I'm not 100% sure if you can have a textview inside a keyboard view).

                                        At the very least, you can implement an approx or pure pythonista editor that does whatever you want, and copy to clipboard when done. With split screen, it wouldn't be too hard to bop back and forth.

                                        1 Reply Last reply Reply Quote 0
                                        • cvp
                                          cvp @trey last edited by cvp

                                          @trey said:

                                          You really don’t have access to a single Bluetooth keyboard

                                          Sorry but I never did think about my iMac Bluetooth keyboard...
                                          I've connected it to my iPad as external keyboard and it works.

                                          Now, it is an AZERTY keyboard, thus it is not coherent with the Pythonista standard keyboard of the custom keyboard extension.

                                          Please, first, try this little script without external keyboard, by pressing &h*, you will see a θ
                                          in your input field, in any app, if you use this script as custom keyboard.

                                          Then, don't change which keyboard is active (no globe key) and connect your Bluetooth keyboard. If your keyboard is coherent with the Pythonista QWERTY standard keyboard, the script will also work. For me, it does not because if I tap & or * on my keyboard, other keys are generated.

                                          Thus, with external keyboard, we get data but not obviously the same key as expected.

                                          Edit: it should be possible to convert received character, in function of its position in standard qwerty Pythonista keyboard into "your" character on your keyboard, at same position.

                                          Hoping that I'm clear enough with my poor English.

                                          #!python3
                                          import keyboard
                                          import ui
                                          
                                          class KeyboardInfoView (ui.View):
                                          	def __init__(self, *args, **kwargs):
                                          		super().__init__(self, *args, **kwargs)
                                          		self.background_color = '#00436e'
                                          		
                                          	def kb_should_insert(self, text):
                                          		if text == '*':
                                          			before,after = keyboard.get_input_context()
                                          			if before[-2] == '&':		# ex: &h*
                                          				ch = before[-1]				# ex: h
                                          				keyboard.backspace(2)	# ex: remove &h
                                          				keyboard.insert_text('\u03B8')	# force θ
                                          				return
                                          		return text
                                          
                                          if __name__ == '__main__':
                                          	v = KeyboardInfoView()
                                          	keyboard.set_view(v, mode='minimized') 
                                          
                                          trey 1 Reply Last reply Reply Quote 1
                                          • trey
                                            trey @cvp last edited by

                                            @cvp said:

                                            @trey said:
                                            Please, first, try this little script without external keyboard, by pressing &h*, you will see a θ
                                            in your input field, in any app, if you use this script as custom keyboard.

                                            Yes.

                                            Then, don't change which keyboard is active (no globe key) and connect your Bluetooth keyboard. If your keyboard is coherent with the Pythonista QWERTY standard keyboard, the script will also work.

                                            No—I get normal QWERTY behavior from the hardware keyboard.

                                            For me, it does not because if I tap & or * on my keyboard, other keys are generated.

                                            Okay, but you can work around that. Here’s a script that—if it works as you say—should put asterisks before any character you type, and since it doesn’t care about the character, it shouldn’t matter QWERTY, AZERTY, or whatever:

                                            
                                            #!python3
                                            import keyboard
                                            import ui
                                            
                                            
                                            class KeyboardInfoView(ui.View):
                                                def __init__(self, *args, **kwargs):
                                                    super().__init__(self, *args, **kwargs)
                                                    self.background_color = '#00436e'
                                            
                                                def kb_should_insert(self, text):
                                                    keyboard.insert_text(u'*')
                                                    return '*'
                                            
                                            
                                            if __name__ == '__main__':
                                                v = KeyboardInfoView()
                                                keyboard.set_view(v, mode='minimized')
                                            

                                            Thus, with external keyboard, we get data but not obviously the same key as expected.

                                            I don’t believe that’s true. Try the above script. If it outputs * when you type hardware keyboard keys, then you are right. But it doesn’t for me. Your AZERTY keyboard shouldn’t matter in this case.

                                            cvp 1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            Powered by NodeBB Forums | Contributors