RSS feed

    Script


  • Single Instance Application with command line interface

    I wanted a python gtk application to open a new window on its first execution and then have subsequent executions send their command line arguments to the initial application rather than starting a new one. Here is the template which provides that functionality:

    download singleinstanceapp.py

    1.  
    2. """
    3. This will only spawn one gtk application at a time. If this command is executed
    4. while an instance is already running, the command line arguments are sent to the
    5. already running application.
    6. """
    7.  
    8. import sys
    9.  
    10. import pygtk
    11. pygtk.require('2.0')
    12. import gtk
    13.  
    14. import socket
    15. import threading
    16. import SocketServer
    17.  
    18. class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    19. def handle(self):
    20. data = self.request.recv(1024)
    21. cur_thread = threading.currentThread()
    22.  
    23. # do something with the request:
    24. self.server.app.label.set_label(data)
    25.  
    26. # could instead of the length of the input, could return error codes, more
    27. # information (if the request was a query), etc. Using a length function
    28. # as a simple example
    29. response = 'string length: %d' % len(data)
    30.  
    31. print 'responding to',data,'with',response
    32. self.request.send(response)
    33.  
    34.  
    35. class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    36. stopped = False
    37. allow_reuse_address = True
    38.  
    39. def serve_forever(self):
    40. while not self.stopped:
    41. self.handle_request()
    42.  
    43. def force_stop(self):
    44. self.server_close()
    45. self.stopped = True
    46. self.create_dummy_request()
    47.  
    48. def create_dummy_request(self):
    49. client(self.server_address[0], self.server_address[1], 'last message for you')
    50.  
    51.  
    52. def client(ip, port, message):
    53. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    54. sock.connect((ip, port))
    55. sock.send(message)
    56. response = sock.recv(1024)
    57. print "Received: %s" % response
    58. sock.close()
    59.  
    60. def start_server(host, port):
    61.  
    62. server = ThreadedTCPServer((host, port), ThreadedTCPRequestHandler)
    63. ip, port = server.server_address
    64.  
    65. # Start a thread with the server -- that thread will then start one
    66. # more thread for each request
    67. server_thread = threading.Thread(target=server.serve_forever)
    68. # Exit the server thread when the main thread terminates
    69. server_thread.setDaemon(True)
    70. server_thread.start()
    71.  
    72. return server
    73.  
    74.  
    75. class SingleInstanceApp:
    76. def destroy(self, widget, data=None):
    77. self.server.force_stop()
    78. gtk.main_quit()
    79. #exit(1) # I'm sorry but mozembed is making a huge pain in my ass
    80.  
    81. def __init__(self, server):
    82. self.server = server
    83.  
    84. # create a new window
    85. self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    86. self.window.set_default_size(300,30)
    87. self.window.connect("destroy", self.destroy)
    88.  
    89. self.label = gtk.Label("hello world")
    90. self.window.add(self.label)
    91.  
    92. self.window.show_all()
    93.  
    94. # and the window
    95. self.window.show()
    96.  
    97. def main(self):
    98. gtk.gdk.threads_init()
    99. gtk.main()
    100.  
    101. if __name__ == "__main__":
    102. # pick some high port number here. Should probably put this into a file
    103. # somewhere.
    104. HOST, PORT = "localhost", 50010
    105.  
    106. server = None
    107. try :
    108. client(HOST, PORT, ' '.join(sys.argv))
    109. print 'an insance was already open'
    110. except socket.error :
    111. exceptionType, exceptionValue, exceptionTraceback = sys.exc_info()
    112. if exceptionValue[0] == 111 :
    113. print 'this is the first instance'
    114. server = start_server(HOST, PORT)
    115. else :
    116. # don't actually know what happened ...
    117. raise
    118.  
    119. app = SingleInstanceApp(server)
    120. server.app = app
    121. app.main()
    122.  

    The first execution of this script starts an asynchronous server on a predetermined port. This port is checked each time the script is run to see if another instance has already been started. If it has, the command line arguments are sent to the existing instance which can react to them however you want.

    download singleinstanceapp.py

    Categories: Code, Script
  • w

    Just remembered that I hadn't published this script that I use fairly often which centers the currently active window on the screen using wmctrl (requires the patch provided)

    wmctrl-patch

    center_active_window.py