2

I have a touch screen application and am trying to launch an onscreen keyboard when the application needs input and close the keyboard to free up screen real estate.

My code below will launch the keyboard, but when I try and terminate() the process, subprocess returns 0 (success) but the application remain open.

How do I close/minimize the keyboard to free up screen real estate?

import subprocess
import platform

class keyboard_mixin(object):
    def __init__(self):
        self.keyboard_process = None

    def show(self):
        if platform.system() == "Linux":
            try:
                cmd_path = "xvkbd"
                self.keyboard_process = subprocess.Popen([cmd_path])
                return
            except OSError:
                pass

        elif platform.system() == "Windows":
            try:
                cmd_path = "C:\\Program Files\\Common Files\\Microsoft Shared\\ink\\TabTip.exe"
                self.keyboard_process = subprocess.Popen([cmd_path], shell=True)
                return
            except OSError:
                pass

            try:
                cmd_path = "C:\\WINDOWS\\system32\\osk.exe"
                self.keyboard_process = subprocess.Popen([cmd_path], shell=True)
                return
            except OSError:
                pass

    def hide(self):
        # TODO: This does not close on windows platform
        if self.keyboard_process is not None:
            self.keyboard_process.terminate()
            self.keyboard_process = None

if __name__ == '__main__':
    osk = keyboard_mixin()
    osk.show()
    osk.hide()
Greg klupar
  • 39
  • 1
  • 6
  • Which Windows on-screen keyboard is actually being invoked? TabTip, or osk? – robert Oct 06 '15 at 22:23
  • 1
    You used `shell=True`, so the process handle is for `cmd.exe`. There is no reason to use `shell=True`. – Eryk Sun Oct 06 '15 at 22:30
  • Both TabTip and osk fail to close. It doesnot matter which one finally gets working and I included both simple to provide options. As for 'shell=True', without this Popen raises an "WindowsError: [Error 740] The requested operation requires elevation" – Greg klupar Oct 07 '15 at 02:14
  • I see. The shell falls back on `ShellExecuteEx` when `CreateProcess` fails. This in turn sets up calling `CreateProcess` to run osk.exe in a way that can't be replicated with `Popen`. In this case, you can use the Windows `taskkill` command to kill cmd along with its child process. Or if you have PyWin32 you can call [`ShellExecuteEx`](http://docs.activestate.com/activepython/3.4/pywin32/shell__ShellExecuteEx_meth.html) and [`TerminateProcess`](http://docs.activestate.com/activepython/3.4/pywin32/win32process__TerminateProcess_meth.html). Or use ctypes to call these WinAPI functions. – Eryk Sun Oct 07 '15 at 06:50

0 Answers0