Squash: Single instance and pop up old instance

This commit is contained in:
Denilson M. Amorim 2015-11-14 20:12:19 -03:00 committed by Peter Surda
parent 46d647460f
commit cf610080b9
3 changed files with 91 additions and 12 deletions

View File

@ -144,7 +144,7 @@ class Main:
shared.daemon = daemon
# is the application already running? If yes then exit.
thisapp = singleton.singleinstance()
thisapp = singleton.singleinstance("", daemon)
import upnp
upnp.createPortMapping()

View File

@ -56,10 +56,23 @@ import subprocess
import datetime
from helper_sql import *
import l10n
import types
from utils import *
from collections import OrderedDict
from account import *
try:
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtNetwork import QLocalSocket, QLocalServer
except Exception as err:
print 'PyBitmessage requires PyQt unless you want to run it as a daemon and interact with it using the API. You can download it from http://www.riverbankcomputing.com/software/pyqt/download or by searching Google for \'PyQt Download\' (without quotes).'
print 'Error message:', err
sys.exit()
try:
_encoding = QtGui.QApplication.UnicodeUTF8
except AttributeError:
print 'QtGui.QApplication.UnicodeUTF8 error:', err
def _translate(context, text):
return QtGui.QApplication.translate(context, text)
@ -4483,8 +4496,70 @@ class UISignaler(QThread):
sys.stderr.write(
'Command sent to UISignaler not recognized: %s\n' % command)
app = None
myapp = None
class MySingleApplication(QApplication):
"""
Listener to allow our Qt form to get focus when another instance of the
application is open.
Based off this nice reimplmentation of MySingleApplication:
http://stackoverflow.com/a/12712362/2679626
"""
# Unique identifier for this application
uuid = '6ec0149b-96e1-4be1-93ab-1465fb3ebf7c'
def __init__(self, *argv):
super(MySingleApplication, self).__init__(*argv)
id = MySingleApplication.uuid
self.server = None
self.is_running = False
socket = QLocalSocket()
socket.connectToServer(id)
self.is_running = socket.waitForConnected()
# Cleanup past crashed servers
if not self.is_running:
if socket.error() == QLocalSocket.ConnectionRefusedError:
socket.disconnectFromServer()
QLocalServer.removeServer(id)
socket.abort()
# Checks if there's an instance of the local server id running
if self.is_running:
# This should be ignored, singleton.py will take care of exiting me.
pass
else:
# Nope, create a local server with this id and assign on_new_connection
# for whenever a second instance tries to run focus the application.
self.server = QLocalServer()
self.server.listen(id)
self.server.newConnection.connect(self.on_new_connection)
def __del__(self):
if self.server:
self.server.close()
def on_new_connection(self):
global myapp
if myapp:
myapp.appIndicatorShow()
def init():
global app
if not app:
app = MySingleApplication(sys.argv)
return app
def run():
app = QtGui.QApplication(sys.argv)
global myapp
app = init()
change_translation(l10n.getTranslationLanguage())
app.setStyleSheet("QStatusBar::item { border: 0px solid black }")
myapp = MyForm()

View File

@ -3,22 +3,26 @@
import sys
import os
import errno
import tempfile
import shared
from multiprocessing import Process
class singleinstance:
"""
Implements a single instance application by creating a lock file based on the full path to the script file.
Implements a single instance application by creating a lock file at appdata.
This is based upon the singleton class from tendo https://github.com/pycontribs/tendo
which is under the Python Software Foundation License version 2
"""
def __init__(self, flavor_id=""):
def __init__(self, flavor_id="", daemon=False):
import sys
self.initialized = False
basename = os.path.splitext(os.path.abspath(sys.argv[0]))[0].replace("/", "-").replace(":", "").replace("\\", "-") + '-%s' % flavor_id + '.lock'
self.lockfile = os.path.normpath(tempfile.gettempdir() + '/' + basename)
self.daemon = daemon;
self.lockfile = os.path.normpath(os.path.join(shared.appdata, 'singleton%s.lock' % flavor_id))
if not self.daemon:
# Tells the already running (if any) application to get focus.
import bitmessageqt
bitmessageqt.init()
if sys.platform == 'win32':
try: