Linux: Add an option to cause calibre to detach from its controlling terminal

This commit is contained in:
Kovid Goyal 2013-11-10 19:43:11 +05:30
parent b712a24e3b
commit 288c24a170
4 changed files with 33 additions and 7 deletions

View File

@ -803,6 +803,20 @@ def load_builtin_fonts():
if u'calibre Symbols' in fam: if u'calibre Symbols' in fam:
_rating_font = u'calibre Symbols' _rating_font = u'calibre Symbols'
def setup_gui_option_parser(parser):
if islinux:
parser.add_option('--detach', default=False, action='store_true',
help='Detach from the controlling terminal, if any (linux only)')
def detach_gui():
if islinux and not DEBUG and sys.stdout.isatty():
# We are a GUI process running in a terminal so detach from the controlling terminal
if os.fork() != 0:
raise SystemExit(0)
os.setsid()
so, se = file(os.devnull, 'a+'), file(os.devnull, 'a+', 0)
os.dup2(so.fileno(), sys.__stdout__.fileno())
os.dup2(se.fileno(), sys.__stderr__.fileno())
class Application(QApplication): class Application(QApplication):
@ -824,7 +838,6 @@ class Application(QApplication):
self._file_open_paths = [] self._file_open_paths = []
self._file_open_lock = RLock() self._file_open_lock = RLock()
self.setup_styles(force_calibre_style) self.setup_styles(force_calibre_style)
if DEBUG: if DEBUG:
def notify(self, receiver, event): def notify(self, receiver, event):
if self.redirect_notify: if self.redirect_notify:

View File

@ -12,8 +12,9 @@ from calibre import prints, plugins, force_unicode
from calibre.constants import (iswindows, __appname__, isosx, DEBUG, islinux, from calibre.constants import (iswindows, __appname__, isosx, DEBUG, islinux,
filesystem_encoding, get_portable_base) filesystem_encoding, get_portable_base)
from calibre.utils.ipc import gui_socket_address, RC from calibre.utils.ipc import gui_socket_address, RC
from calibre.gui2 import (ORG_NAME, APP_UID, initialize_file_icon_provider, from calibre.gui2 import (
Application, choose_dir, error_dialog, question_dialog, gprefs) ORG_NAME, APP_UID, initialize_file_icon_provider, Application, choose_dir,
error_dialog, question_dialog, gprefs, detach_gui, setup_gui_option_parser)
from calibre.gui2.main_window import option_parser as _option_parser from calibre.gui2.main_window import option_parser as _option_parser
from calibre.utils.config import prefs, dynamic from calibre.utils.config import prefs, dynamic
@ -46,6 +47,7 @@ path_to_ebook to the database.
help=_('Cause a running calibre instance, if any, to be' help=_('Cause a running calibre instance, if any, to be'
' shutdown. Note that if there are running jobs, they ' ' shutdown. Note that if there are running jobs, they '
'will be silently aborted, so use with care.')) 'will be silently aborted, so use with care.'))
setup_gui_option_parser(parser)
return parser return parser
def find_portable_library(): def find_portable_library():
@ -84,6 +86,8 @@ def find_portable_library():
def init_qt(args): def init_qt(args):
parser = option_parser() parser = option_parser()
opts, args = parser.parse_args(args) opts, args = parser.parse_args(args)
if getattr(opts, 'detach', False):
detach_gui()
find_portable_library() find_portable_library()
if opts.with_library is not None: if opts.with_library is not None:
libpath = os.path.expanduser(opts.with_library) libpath = os.path.expanduser(opts.with_library)

View File

@ -11,17 +11,20 @@ import sys, os
from PyQt4.Qt import QIcon from PyQt4.Qt import QIcon
from calibre.constants import islinux from calibre.constants import islinux
from calibre.gui2 import Application, ORG_NAME, APP_UID from calibre.gui2 import Application, ORG_NAME, APP_UID, setup_gui_option_parser, detach_gui
from calibre.ptempfile import reset_base_dir from calibre.ptempfile import reset_base_dir
from calibre.utils.config import OptionParser from calibre.utils.config import OptionParser
from calibre.gui2.tweak_book.ui import Main from calibre.gui2.tweak_book.ui import Main
def option_parser(): def option_parser():
return OptionParser('''\ parser = OptionParser('''\
%prog [opts] [path_to_ebook] %prog [opts] [path_to_ebook]
Launch the calibre tweak book tool. Launch the calibre tweak book tool.
''') ''')
setup_gui_option_parser(parser)
return parser
def main(args=sys.argv): def main(args=sys.argv):
# Ensure we can continue to function if GUI is closed # Ensure we can continue to function if GUI is closed
@ -30,6 +33,8 @@ def main(args=sys.argv):
parser = option_parser() parser = option_parser()
opts, args = parser.parse_args(args) opts, args = parser.parse_args(args)
if getattr(opts, 'detach', False):
detach_gui()
override = 'calibre-tweak-book' if islinux else None override = 'calibre-tweak-book' if islinux else None
app = Application(args, override_program_name=override) app = Application(args, override_program_name=override)
app.load_builtin_fonts() app.load_builtin_fonts()

View File

@ -18,7 +18,7 @@ from calibre.gui2.viewer.toc import TOC
from calibre.gui2.widgets import ProgressIndicator from calibre.gui2.widgets import ProgressIndicator
from calibre.gui2.main_window import MainWindow from calibre.gui2.main_window import MainWindow
from calibre.gui2 import (Application, ORG_NAME, APP_UID, choose_files, from calibre.gui2 import (Application, ORG_NAME, APP_UID, choose_files,
info_dialog, error_dialog, open_url, available_height) info_dialog, error_dialog, open_url, available_height, setup_gui_option_parser, detach_gui)
from calibre.ebooks.oeb.iterator.book import EbookIterator from calibre.ebooks.oeb.iterator.book import EbookIterator
from calibre.ebooks import DRMError from calibre.ebooks import DRMError
from calibre.constants import islinux, filesystem_encoding from calibre.constants import islinux, filesystem_encoding
@ -1183,11 +1183,13 @@ def config(defaults=None):
def option_parser(): def option_parser():
c = config() c = config()
return c.option_parser(usage=_('''\ parser = c.option_parser(usage=_('''\
%prog [options] file %prog [options] file
View an ebook. View an ebook.
''')) '''))
setup_gui_option_parser(parser)
return parser
def main(args=sys.argv): def main(args=sys.argv):
@ -1197,6 +1199,8 @@ def main(args=sys.argv):
parser = option_parser() parser = option_parser()
opts, args = parser.parse_args(args) opts, args = parser.parse_args(args)
if getattr(opts, 'detach', False):
detach_gui()
try: try:
open_at = float(opts.open_at) open_at = float(opts.open_at)
except: except: