mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Linux: Add an option to cause calibre to detach from its controlling terminal
This commit is contained in:
parent
b712a24e3b
commit
288c24a170
@ -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:
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user