diff --git a/src/application.py b/src/application.py
index b4f2da923..d023d03a4 100644
--- a/src/application.py
+++ b/src/application.py
@@ -18,8 +18,16 @@
## along with Gajim. If not, see .
##
+import sys
+import os
+import warnings
+import logging
from gi.repository import GLib, Gio, Gtk
+from common import i18n
from common import logging_helpers
+logging_helpers.init(sys.stderr.isatty())
+
+log = logging.getLogger('gajim.gajim')
class GajimApplication(Gtk.Application):
@@ -63,6 +71,363 @@ class GajimApplication(Gtk.Application):
def do_activate(self):
Gtk.Application.do_activate(self)
+ if os.name == 'nt':
+ import locale
+ import gettext
+ APP = 'gajim'
+ DIR = '../po'
+ lang, enc = locale.getdefaultlocale()
+ os.environ['LANG'] = lang
+ gettext.bindtextdomain(APP, DIR)
+ gettext.textdomain(APP)
+ gettext.install(APP, DIR)
+
+ # locale.setlocale(locale.LC_ALL, '')
+ # import ctypes
+ # import ctypes.util
+ # libintl_path = ctypes.util.find_library('intl')
+ # if libintl_path == None:
+ # local_intl = os.path.join('gtk', 'bin', 'intl.dll')
+ # if os.path.exists(local_intl):
+ # libintl_path = local_intl
+ # if libintl_path == None:
+ # raise ImportError('intl.dll library not found')
+ # libintl = ctypes.cdll.LoadLibrary(libintl_path)
+ # libintl.bindtextdomain(APP, DIR)
+ # libintl.bind_textdomain_codeset(APP, 'UTF-8')
+
+ if os.name == 'nt':
+ # needed for docutils
+ sys.path.append('.')
+
+ import locale
+
+ import common.configpaths
+ common.configpaths.gajimpaths.init(
+ self.config_path, self.profile, self.profile_separation)
+
+ if os.name == 'nt':
+ plugins_locale_dir = os.path.join(common.configpaths.gajimpaths[
+ 'PLUGINS_USER'], 'locale').encode(locale.getpreferredencoding())
+ # libintl.bindtextdomain('gajim_plugins', plugins_locale_dir)
+ # libintl.bind_textdomain_codeset('gajim_plugins', 'UTF-8')
+
+ class MyStderr(object):
+ _file = None
+ _error = None
+ def write(self, text):
+ fname = os.path.join(common.configpaths.gajimpaths.cache_root,
+ os.path.split(sys.executable)[1]+'.log')
+ if self._file is None and self._error is None:
+ try:
+ self._file = open(fname, 'a')
+ except Exception as details:
+ self._error = details
+ if self._file is not None:
+ self._file.write(text)
+ self._file.flush()
+ def flush(self):
+ if self._file is not None:
+ self._file.flush()
+
+ sys.stderr = MyStderr()
+
+ # PyGTK2.10+ only throws a warning
+ warnings.filterwarnings('error', module='Gtk')
+ try:
+ from gi.repository import GObject
+ GObject.set_prgname('gajim')
+ except Warning as msg2:
+ if str(msg2) == 'could not open display':
+ print(_('Gajim needs X server to run. Quiting...'), file=sys.stderr)
+ else:
+ print(_('importing PyGTK failed: %s') % str(msg2), file=sys.stderr)
+ sys.exit()
+ warnings.resetwarnings()
+
+ if os.name == 'nt':
+ warnings.filterwarnings(action='ignore')
+
+ if Gtk.Widget.get_default_direction() == Gtk.TextDirection.RTL:
+ i18n.direction_mark = '\u200F'
+ pritext = ''
+
+ from common import exceptions
+ try:
+ from common import gajim
+ except exceptions.DatabaseMalformed:
+ pritext = _('Database Error')
+ sectext = _('The database file (%s) cannot be read. Try to repair it (see '
+ 'http://trac.gajim.org/wiki/DatabaseBackup) or remove it (all history '
+ 'will be lost).') % common.logger.LOG_DB_PATH
+ else:
+ from common import logger
+ gajim.logger = logger.Logger()
+ from common import caps_cache
+ caps_cache.initialize(gajim.logger)
+ from common import dbus_support
+ if dbus_support.supported:
+ from music_track_listener import MusicTrackListener
+
+ from ctypes import CDLL
+ from ctypes.util import find_library
+ import platform
+
+ sysname = platform.system()
+ if sysname in ('Linux', 'FreeBSD', 'OpenBSD', 'NetBSD'):
+ libc = CDLL(find_library('c'))
+
+ # The constant defined in which is used to set the name
+ # of the process.
+ PR_SET_NAME = 15
+
+ if sysname == 'Linux':
+ libc.prctl(PR_SET_NAME, 'gajim')
+ elif sysname in ('FreeBSD', 'OpenBSD', 'NetBSD'):
+ libc.setproctitle('gajim')
+
+ # if Gtk.pygtk_version < (2, 22, 0):
+ # pritext = _('Gajim needs PyGTK 2.22 or above')
+ # sectext = _('Gajim needs PyGTK 2.22 or above to run. Quiting...')
+ # elif Gtk.gtk_version < (2, 22, 0):
+ # if (Gtk.get_major_version(), Gtk.get_minor_version(),
+ # Gtk.get_micro_version()) < (2, 22, 0):
+ # pritext = _('Gajim needs GTK 2.22 or above')
+ # sectext = _('Gajim needs GTK 2.22 or above to run. Quiting...')
+
+ from common import check_paths
+
+ if os.name == 'nt':
+ try:
+ import winsound # windows-only built-in module for playing wav
+ import win32api # do NOT remove. we req this module
+ except Exception:
+ pritext = _('Gajim needs pywin32 to run')
+ sectext = _('Please make sure that Pywin32 is installed on your '
+ 'system. You can get it at %s') % \
+ 'http://sourceforge.net/project/showfiles.php?group_id=78018'
+
+ if pritext:
+ dlg = Gtk.MessageDialog(None,
+ Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL,
+ Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, message_format = pritext)
+
+ dlg.format_secondary_text(sectext)
+ dlg.run()
+ dlg.destroy()
+ sys.exit()
+
+ del pritext
+
+ #import gtkexcepthook
+
+ import signal
+ import gtkgui_helpers
+
+ gajimpaths = common.configpaths.gajimpaths
+
+ pid_filename = gajimpaths['PID_FILE']
+ config_filename = gajimpaths['CONFIG_FILE']
+
+ # Seed the OpenSSL pseudo random number generator from file and initialize
+ RNG_SEED = gajimpaths['RNG_SEED']
+ PYOPENSSL_PRNG_PRESENT = False
+ try:
+ import OpenSSL.rand
+ from common import crypto
+ PYOPENSSL_PRNG_PRESENT = True
+ # Seed from file
+ try:
+ OpenSSL.rand.load_file(RNG_SEED)
+ except TypeError:
+ OpenSSL.rand.load_file(RNG_SEED.encode('utf-8'))
+ crypto.add_entropy_sources_OpenSSL()
+ try:
+ OpenSSL.rand.write_file(RNG_SEED)
+ except TypeError:
+ OpenSSL.rand.write_file(RNG_SEED.encode('utf-8'))
+ except ImportError:
+ log.info("PyOpenSSL PRNG not available")
+
+ import traceback
+ import errno
+ import dialogs
+
+ def pid_alive():
+ try:
+ pf = open(pid_filename)
+ except IOError:
+ # probably file not found
+ return False
+
+ try:
+ pid = int(pf.read().strip())
+ pf.close()
+ except Exception:
+ traceback.print_exc()
+ # PID file exists, but something happened trying to read PID
+ # Could be 0.10 style empty PID file, so assume Gajim is running
+ return True
+
+ if os.name == 'nt':
+ try:
+ from ctypes import (windll, c_ulong, c_int, Structure, c_char)
+ from ctypes import (POINTER, pointer, sizeof)
+ except Exception:
+ return True
+
+ class PROCESSENTRY32(Structure):
+ _fields_ = [
+ ('dwSize', c_ulong, ),
+ ('cntUsage', c_ulong, ),
+ ('th32ProcessID', c_ulong, ),
+ ('th32DefaultHeapID', c_ulong, ),
+ ('th32ModuleID', c_ulong, ),
+ ('cntThreads', c_ulong, ),
+ ('th32ParentProcessID', c_ulong, ),
+ ('pcPriClassBase', c_ulong, ),
+ ('dwFlags', c_ulong, ),
+ ('szExeFile', c_char*512, ),
+ ]
+
+ kernel = windll.kernel32
+ kernel.CreateToolhelp32Snapshot.argtypes = c_ulong, c_ulong,
+ kernel.CreateToolhelp32Snapshot.restype = c_int
+ kernel.Process32First.argtypes = c_int, POINTER(PROCESSENTRY32),
+ kernel.Process32First.restype = c_int
+ kernel.Process32Next.argtypes = c_int, POINTER(PROCESSENTRY32),
+ kernel.Process32Next.restype = c_int
+
+ def get_p(pid_):
+ TH32CS_SNAPPROCESS = 2
+ CreateToolhelp32Snapshot = kernel.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
+ assert CreateToolhelp32Snapshot > 0, 'CreateToolhelp32Snapshot failed'
+ pe32 = PROCESSENTRY32()
+ pe32.dwSize = sizeof( PROCESSENTRY32 )
+ f3 = kernel.Process32First(CreateToolhelp32Snapshot, pointer(pe32))
+ while f3:
+ if pe32.th32ProcessID == pid_:
+ return pe32.szExeFile
+ f3 = kernel.Process32Next(CreateToolhelp32Snapshot, pointer(pe32))
+
+ if get_p(pid) in ('python.exe', 'gajim.exe'):
+ return True
+ return False
+ try:
+ if not os.path.exists('/proc'):
+ return True # no /proc, assume Gajim is running
+
+ try:
+ f1 = open('/proc/%d/cmdline'% pid)
+ except IOError as e1:
+ if e1.errno == errno.ENOENT:
+ return False # file/pid does not exist
+ raise
+
+ n = f1.read().lower()
+ f1.close()
+ if n.find('gajim') < 0:
+ return False
+ return True # Running Gajim found at pid
+ except Exception:
+ traceback.print_exc()
+
+ # If we are here, pidfile exists, but some unexpected error occured.
+ # Assume Gajim is running.
+ return True
+
+ def show_remote_gajim_roster():
+ try:
+ import dbus
+
+ OBJ_PATH = '/org/gajim/dbus/RemoteObject'
+ INTERFACE = 'org.gajim.dbus.RemoteInterface'
+ SERVICE = 'org.gajim.dbus'
+
+ # Attempt to call show_roster
+ dbus.Interface(dbus.SessionBus().get_object(SERVICE, OBJ_PATH), INTERFACE).__getattr__("show_roster")()
+
+ return True
+ except Exception:
+ return False
+
+ if pid_alive():
+ if (show_remote_gajim_roster()):
+ print("Gajim is already running, bringing the roster to front...")
+ sys.exit(0)
+ pixs = []
+ for size in (16, 32, 48, 64, 128):
+ pix = gtkgui_helpers.get_icon_pixmap('gajim', size)
+ if pix:
+ pixs.append(pix)
+ if pixs:
+ # set the icon to all windows
+ Gtk.Window.set_default_icon_list(pixs)
+ pritext = _('Gajim is already running')
+ sectext = _('Another instance of Gajim seems to be running\nRun anyway?')
+ dialog = dialogs.YesNoDialog(pritext, sectext)
+ dialog.popup()
+ if dialog.run() != Gtk.ResponseType.YES:
+ sys.exit(3)
+ dialog.destroy()
+ # run anyway, delete pid and useless global vars
+ if os.path.exists(pid_filename):
+ os.remove(pid_filename)
+ del pix
+ del pritext
+ del sectext
+ dialog.destroy()
+
+ # Create .gajim dir
+ pid_dir = os.path.dirname(pid_filename)
+ if not os.path.exists(pid_dir):
+ check_paths.create_path(pid_dir)
+ # Create pid file
+ try:
+ f2 = open(pid_filename, 'w')
+ f2.write(str(os.getpid()))
+ f2.close()
+ except IOError as e2:
+ dlg = dialogs.ErrorDialog(_('Disk Write Error'), str(e2))
+ dlg.run()
+ dlg.destroy()
+ sys.exit()
+ del pid_dir
+
+ def on_exit():
+ # Save the entropy from OpenSSL PRNG
+ if PYOPENSSL_PRNG_PRESENT:
+ try:
+ OpenSSL.rand.write_file(RNG_SEED)
+ except TypeError:
+ OpenSSL.rand.write_file(RNG_SEED.encode('utf-8'))
+ # delete pid file on normal exit
+ if os.path.exists(pid_filename):
+ os.remove(pid_filename)
+ # Shutdown GUI and save config
+ if hasattr(gajim.interface, 'roster') and gajim.interface.roster:
+ gajim.interface.roster.prepare_quit()
+
+ import atexit
+ atexit.register(on_exit)
+
+ from gui_interface import Interface
+
+ def sigint_cb(num, stack):
+ sys.exit(5)
+ # ^C exits the application normally to delete pid file
+ signal.signal(signal.SIGINT, sigint_cb)
+ signal.signal(signal.SIGTERM, sigint_cb)
+
+ log.info("Encodings: d:%s, fs:%s, p:%s", sys.getdefaultencoding(), \
+ sys.getfilesystemencoding(), locale.getpreferredencoding())
+
+ check_paths.check_and_possibly_create_paths()
+
+ interface = Interface()
+ interface.run(self)
+
+
def do_command_line(self, command_line: Gio.ApplicationCommandLine) -> int:
Gtk.Application.do_command_line(self, command_line)
options = command_line.get_options_dict()
diff --git a/src/gajim.py b/src/gajim.py
index 580b2b085..b87804132 100644
--- a/src/gajim.py
+++ b/src/gajim.py
@@ -44,7 +44,6 @@ if '--version' in sys.argv or '-V' in sys.argv:
import os
import warnings
-import OpenSSL
if os.name == 'nt':
log_path = os.path.join(os.environ['APPDATA'], 'Gajim')
@@ -80,381 +79,7 @@ if V(nbxmpp.__version__) < V(MIN_NBXMPP_VER):
print('Gajim needs python-nbxmpp >= %s to run. Quiting...' % MIN_NBXMPP_VER)
sys.exit(1)
-if os.name == 'nt':
- import locale
- import gettext
- APP = 'gajim'
- DIR = '../po'
- lang, enc = locale.getdefaultlocale()
- os.environ['LANG'] = lang
- gettext.bindtextdomain(APP, DIR)
- gettext.textdomain(APP)
- gettext.install(APP, DIR)
-
-# locale.setlocale(locale.LC_ALL, '')
-# import ctypes
-# import ctypes.util
-# libintl_path = ctypes.util.find_library('intl')
-# if libintl_path == None:
-# local_intl = os.path.join('gtk', 'bin', 'intl.dll')
-# if os.path.exists(local_intl):
-# libintl_path = local_intl
-# if libintl_path == None:
-# raise ImportError('intl.dll library not found')
-# libintl = ctypes.cdll.LoadLibrary(libintl_path)
-# libintl.bindtextdomain(APP, DIR)
-# libintl.bind_textdomain_codeset(APP, 'UTF-8')
-
-if os.name == 'nt':
- # needed for docutils
- sys.path.append('.')
-
-from common import logging_helpers
-logging_helpers.init(sys.stderr.isatty())
-
-import logging
-# gajim.gui or gajim.gtk more appropriate ?
-log = logging.getLogger('gajim.gajim')
-
-
-from common import i18n
-import locale
from application import GajimApplication
app = GajimApplication()
app.run(sys.argv)
-
-import common.configpaths
-common.configpaths.gajimpaths.init(
- app.config_path, app.profile, app.profile_separation)
-
-if os.name == 'nt':
- plugins_locale_dir = os.path.join(common.configpaths.gajimpaths[
- 'PLUGINS_USER'], 'locale').encode(locale.getpreferredencoding())
-# libintl.bindtextdomain('gajim_plugins', plugins_locale_dir)
-# libintl.bind_textdomain_codeset('gajim_plugins', 'UTF-8')
-
- class MyStderr(object):
- _file = None
- _error = None
- def write(self, text):
- fname = os.path.join(common.configpaths.gajimpaths.cache_root,
- os.path.split(sys.executable)[1]+'.log')
- if self._file is None and self._error is None:
- try:
- self._file = open(fname, 'a')
- except Exception as details:
- self._error = details
- if self._file is not None:
- self._file.write(text)
- self._file.flush()
- def flush(self):
- if self._file is not None:
- self._file.flush()
-
- sys.stderr = MyStderr()
-
-# PyGTK2.10+ only throws a warning
-warnings.filterwarnings('error', module='Gtk')
-try:
- from gi.repository import GObject
- GObject.set_prgname('gajim')
- from gi.repository import Gtk
- from gi.repository import Gdk
- from gi.repository import GLib
-except Warning as msg2:
- if str(msg2) == 'could not open display':
- print(_('Gajim needs X server to run. Quiting...'), file=sys.stderr)
- else:
- print(_('importing PyGTK failed: %s') % str(msg2), file=sys.stderr)
- sys.exit()
-warnings.resetwarnings()
-
-
-if os.name == 'nt':
- warnings.filterwarnings(action='ignore')
-
-if Gtk.Widget.get_default_direction() == Gtk.TextDirection.RTL:
- i18n.direction_mark = '\u200F'
-pritext = ''
-
-from common import exceptions
-try:
- from common import gajim
-except exceptions.DatabaseMalformed:
- pritext = _('Database Error')
- sectext = _('The database file (%s) cannot be read. Try to repair it (see '
- 'http://trac.gajim.org/wiki/DatabaseBackup) or remove it (all history '
- 'will be lost).') % common.logger.LOG_DB_PATH
-else:
- from common import logger
- gajim.logger = logger.Logger()
- from common import caps_cache
- caps_cache.initialize(gajim.logger)
- from common import dbus_support
- if dbus_support.supported:
- from music_track_listener import MusicTrackListener
-
- from ctypes import CDLL
- from ctypes.util import find_library
- import platform
-
- sysname = platform.system()
- if sysname in ('Linux', 'FreeBSD', 'OpenBSD', 'NetBSD'):
- libc = CDLL(find_library('c'))
-
- # The constant defined in which is used to set the name
- # of the process.
- PR_SET_NAME = 15
-
- if sysname == 'Linux':
- libc.prctl(PR_SET_NAME, 'gajim')
- elif sysname in ('FreeBSD', 'OpenBSD', 'NetBSD'):
- libc.setproctitle('gajim')
-
-# if Gtk.pygtk_version < (2, 22, 0):
-# pritext = _('Gajim needs PyGTK 2.22 or above')
-# sectext = _('Gajim needs PyGTK 2.22 or above to run. Quiting...')
-# elif Gtk.gtk_version < (2, 22, 0):
-# if (Gtk.get_major_version(), Gtk.get_minor_version(),
-# Gtk.get_micro_version()) < (2, 22, 0):
-# pritext = _('Gajim needs GTK 2.22 or above')
-# sectext = _('Gajim needs GTK 2.22 or above to run. Quiting...')
-
- from common import check_paths
-
- if os.name == 'nt':
- try:
- import winsound # windows-only built-in module for playing wav
- import win32api # do NOT remove. we req this module
- except Exception:
- pritext = _('Gajim needs pywin32 to run')
- sectext = _('Please make sure that Pywin32 is installed on your '
- 'system. You can get it at %s') % \
- 'http://sourceforge.net/project/showfiles.php?group_id=78018'
-
-if pritext:
- dlg = Gtk.MessageDialog(None,
- Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL,
- Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, message_format = pritext)
-
- dlg.format_secondary_text(sectext)
- dlg.run()
- dlg.destroy()
- sys.exit()
-
-del pritext
-
-#import gtkexcepthook
-
-import signal
-import gtkgui_helpers
-
-gajimpaths = common.configpaths.gajimpaths
-
-pid_filename = gajimpaths['PID_FILE']
-config_filename = gajimpaths['CONFIG_FILE']
-
-# Seed the OpenSSL pseudo random number generator from file and initialize
-RNG_SEED = gajimpaths['RNG_SEED']
-PYOPENSSL_PRNG_PRESENT = False
-try:
- import OpenSSL.rand
- from common import crypto
- PYOPENSSL_PRNG_PRESENT = True
- # Seed from file
- try:
- OpenSSL.rand.load_file(RNG_SEED)
- except TypeError:
- OpenSSL.rand.load_file(RNG_SEED.encode('utf-8'))
- crypto.add_entropy_sources_OpenSSL()
- try:
- OpenSSL.rand.write_file(RNG_SEED)
- except TypeError:
- OpenSSL.rand.write_file(RNG_SEED.encode('utf-8'))
-except ImportError:
- log.info("PyOpenSSL PRNG not available")
-
-import traceback
-import errno
-import dialogs
-
-def pid_alive():
- try:
- pf = open(pid_filename)
- except IOError:
- # probably file not found
- return False
-
- try:
- pid = int(pf.read().strip())
- pf.close()
- except Exception:
- traceback.print_exc()
- # PID file exists, but something happened trying to read PID
- # Could be 0.10 style empty PID file, so assume Gajim is running
- return True
-
- if os.name == 'nt':
- try:
- from ctypes import (windll, c_ulong, c_int, Structure, c_char)
- from ctypes import (POINTER, pointer, sizeof)
- except Exception:
- return True
-
- class PROCESSENTRY32(Structure):
- _fields_ = [
- ('dwSize', c_ulong, ),
- ('cntUsage', c_ulong, ),
- ('th32ProcessID', c_ulong, ),
- ('th32DefaultHeapID', c_ulong, ),
- ('th32ModuleID', c_ulong, ),
- ('cntThreads', c_ulong, ),
- ('th32ParentProcessID', c_ulong, ),
- ('pcPriClassBase', c_ulong, ),
- ('dwFlags', c_ulong, ),
- ('szExeFile', c_char*512, ),
- ]
-
- kernel = windll.kernel32
- kernel.CreateToolhelp32Snapshot.argtypes = c_ulong, c_ulong,
- kernel.CreateToolhelp32Snapshot.restype = c_int
- kernel.Process32First.argtypes = c_int, POINTER(PROCESSENTRY32),
- kernel.Process32First.restype = c_int
- kernel.Process32Next.argtypes = c_int, POINTER(PROCESSENTRY32),
- kernel.Process32Next.restype = c_int
-
- def get_p(pid_):
- TH32CS_SNAPPROCESS = 2
- CreateToolhelp32Snapshot = kernel.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
- assert CreateToolhelp32Snapshot > 0, 'CreateToolhelp32Snapshot failed'
- pe32 = PROCESSENTRY32()
- pe32.dwSize = sizeof( PROCESSENTRY32 )
- f3 = kernel.Process32First(CreateToolhelp32Snapshot, pointer(pe32))
- while f3:
- if pe32.th32ProcessID == pid_:
- return pe32.szExeFile
- f3 = kernel.Process32Next(CreateToolhelp32Snapshot, pointer(pe32))
-
- if get_p(pid) in ('python.exe', 'gajim.exe'):
- return True
- return False
- try:
- if not os.path.exists('/proc'):
- return True # no /proc, assume Gajim is running
-
- try:
- f1 = open('/proc/%d/cmdline'% pid)
- except IOError as e1:
- if e1.errno == errno.ENOENT:
- return False # file/pid does not exist
- raise
-
- n = f1.read().lower()
- f1.close()
- if n.find('gajim') < 0:
- return False
- return True # Running Gajim found at pid
- except Exception:
- traceback.print_exc()
-
- # If we are here, pidfile exists, but some unexpected error occured.
- # Assume Gajim is running.
- return True
-
-def show_remote_gajim_roster():
- try:
- import dbus
-
- OBJ_PATH = '/org/gajim/dbus/RemoteObject'
- INTERFACE = 'org.gajim.dbus.RemoteInterface'
- SERVICE = 'org.gajim.dbus'
-
- # Attempt to call show_roster
- dbus.Interface(dbus.SessionBus().get_object(SERVICE, OBJ_PATH), INTERFACE).__getattr__("show_roster")()
-
- return True
- except Exception:
- return False
-
-if pid_alive():
- if (show_remote_gajim_roster()):
- print("Gajim is already running, bringing the roster to front...")
- sys.exit(0)
- pixs = []
- for size in (16, 32, 48, 64, 128):
- pix = gtkgui_helpers.get_icon_pixmap('gajim', size)
- if pix:
- pixs.append(pix)
- if pixs:
- # set the icon to all windows
- Gtk.Window.set_default_icon_list(pixs)
- pritext = _('Gajim is already running')
- sectext = _('Another instance of Gajim seems to be running\nRun anyway?')
- dialog = dialogs.YesNoDialog(pritext, sectext)
- dialog.popup()
- if dialog.run() != Gtk.ResponseType.YES:
- sys.exit(3)
- dialog.destroy()
- # run anyway, delete pid and useless global vars
- if os.path.exists(pid_filename):
- os.remove(pid_filename)
- del pix
- del pritext
- del sectext
- dialog.destroy()
-
-# Create .gajim dir
-pid_dir = os.path.dirname(pid_filename)
-if not os.path.exists(pid_dir):
- check_paths.create_path(pid_dir)
-# Create pid file
-try:
- f2 = open(pid_filename, 'w')
- f2.write(str(os.getpid()))
- f2.close()
-except IOError as e2:
- dlg = dialogs.ErrorDialog(_('Disk Write Error'), str(e2))
- dlg.run()
- dlg.destroy()
- sys.exit()
-del pid_dir
-
-def on_exit():
- # Save the entropy from OpenSSL PRNG
- if PYOPENSSL_PRNG_PRESENT:
- try:
- OpenSSL.rand.write_file(RNG_SEED)
- except TypeError:
- OpenSSL.rand.write_file(RNG_SEED.encode('utf-8'))
- # delete pid file on normal exit
- if os.path.exists(pid_filename):
- os.remove(pid_filename)
- # Shutdown GUI and save config
- if hasattr(gajim.interface, 'roster') and gajim.interface.roster:
- gajim.interface.roster.prepare_quit()
-
-import atexit
-atexit.register(on_exit)
-
-from gui_interface import Interface
-
-if __name__.endswith('__main__'):
- def sigint_cb(num, stack):
- sys.exit(5)
- # ^C exits the application normally to delete pid file
- signal.signal(signal.SIGINT, sigint_cb)
- signal.signal(signal.SIGTERM, sigint_cb)
-
- log.info("Encodings: d:%s, fs:%s, p:%s", sys.getdefaultencoding(), \
- sys.getfilesystemencoding(), locale.getpreferredencoding())
-
- check_paths.check_and_possibly_create_paths()
-
- interface = Interface()
- interface.run()
-
- try:
- Gtk.main()
- except KeyboardInterrupt:
- print('KeyboardInterrupt', file=sys.stderr)
diff --git a/src/gui_interface.py b/src/gui_interface.py
index 7967fefb5..a1f1068d5 100644
--- a/src/gui_interface.py
+++ b/src/gui_interface.py
@@ -2719,11 +2719,11 @@ class Interface:
view.updateNamespace({'gajim': gajim})
gajim.ipython_window = window
- def run(self):
+ def run(self, app):
if gajim.config.get('trayicon') != 'never':
self.show_systray()
- self.roster = roster_window.RosterWindow()
+ self.roster = roster_window.RosterWindow(app)
if self.msg_win_mgr.mode == \
MessageWindowMgr.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER:
self.msg_win_mgr.create_window(None, None, None)
diff --git a/src/roster_window.py b/src/roster_window.py
index f54b95d99..4ca0a644e 100644
--- a/src/roster_window.py
+++ b/src/roster_window.py
@@ -94,7 +94,7 @@ empty_pixbuf = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 1, 1)
empty_pixbuf.fill(0xffffff00)
-class RosterWindow:
+class RosterWindow(Gtk.ApplicationWindow):
"""
Class for main window of the GTK+ interface
"""
@@ -2479,7 +2479,7 @@ class RosterWindow:
When we quit the gtk interface - exit gtk
"""
self.prepare_quit()
- Gtk.main_quit()
+ self.application.quit()
def on_quit_request(self, widget=None):
"""
@@ -6178,7 +6178,8 @@ class RosterWindow:
###
################################################################################
- def __init__(self):
+ def __init__(self, app):
+ self.application = app
self.filtering = False
self.starting = False
self.starting_filtering = False
@@ -6195,6 +6196,7 @@ class RosterWindow:
self.xml = gtkgui_helpers.get_gtk_builder('roster_window.ui')
self.window = self.xml.get_object('roster_window')
self.hpaned = self.xml.get_object('roster_hpaned')
+ self.window.set_application(app)
gajim.interface.msg_win_mgr = MessageWindowMgr(self.window, self.hpaned)
gajim.interface.msg_win_mgr.connect('window-delete',
self.on_message_window_delete)