[jhbuild: 13/60] [gui] use vte widget if available
- From: Frederic Peters <fpeters src gnome org>
- To: svn-commits-list gnome org
- Subject: [jhbuild: 13/60] [gui] use vte widget if available
- Date: Sat, 6 Jun 2009 09:48:42 -0400 (EDT)
commit 2b178ee22756358fcb9374124c642c5d80a585bb
Author: Frédéric Péters <fpeters 0d be>
Date: Sat May 16 23:29:15 2009 +0200
[gui] use vte widget if available
---
jhbuild/frontends/gtkui.py | 179 ++++++++++++++++++++++++++------------------
1 files changed, 106 insertions(+), 73 deletions(-)
diff --git a/jhbuild/frontends/gtkui.py b/jhbuild/frontends/gtkui.py
index c4376f0..3f79d2d 100644
--- a/jhbuild/frontends/gtkui.py
+++ b/jhbuild/frontends/gtkui.py
@@ -32,7 +32,10 @@ import subprocess
import gobject
import gtk
import gtk.glade
-import vte
+try:
+ import vte
+except ImportError:
+ vte = None
#FIXME: would be nice if we ran w/o GConf, do a try...except block around
# the import and then set have_gconf to false
@@ -54,7 +57,6 @@ class AppWindow(gtk.Window, buildscript.BuildScript):
buildscript.BuildScript.__init__(self, config)
self.config = config
gtk.Window.__init__(self)
- self.set_resizable(False) # necessary for the expander to behave properly
theme = gtk.icon_theme_get_default()
gtk.window_set_default_icon_list(
theme.load_icon('applications-development', 16, ()),
@@ -130,11 +132,17 @@ class AppWindow(gtk.Window, buildscript.BuildScript):
buttonbox.add(button)
buttonbox.set_child_secondary(button, True)
- expander = gtk.Expander(_('Terminal'))
- expander.set_expanded(False)
- app_vbox.pack_start(expander, fill=False, expand=False)
- self.terminal = vte.Terminal()
- expander.add(self.terminal)
+ if vte:
+ expander = gtk.Expander(_('Terminal'))
+ expander.set_expanded(False)
+ app_vbox.pack_start(expander, fill=True, expand=True)
+ sclwin = gtk.ScrolledWindow()
+ sclwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
+ expander.add(sclwin)
+ self.terminal = vte.Terminal()
+ self.terminal.connect('eof', self.on_vte_eof_cb)
+ self.terminal.connect('child-exited', self.on_vte_child_exit_cb)
+ sclwin.add(self.terminal)
app_vbox.show_all()
self.add(app_vbox)
@@ -208,74 +216,99 @@ class AppWindow(gtk.Window, buildscript.BuildScript):
def execute(self, command, hint=None, cwd=None, extra_env=None):
return_code = -1
- print 'executing:', command
-
- kws = {
- 'close_fds': True,
- 'shell': isinstance(command, (str,unicode)),
- 'stdin': subprocess.PIPE,
- 'stdout': subprocess.PIPE,
- 'stderr': subprocess.PIPE,
- }
-
- if cwd is not None:
- kws['cwd'] = cwd
-
- if extra_env is not None:
- kws['env'] = os.environ.copy()
- kws['env'].update(extra_env)
-
- try:
- p = subprocess.Popen(command, **kws)
- except OSError, e:
- raise CommandError(str(e))
-
- p.stdin.close()
-
- def make_non_blocking(fd):
- fl = fcntl.fcntl(fd, fcntl.F_GETFL)
- fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NDELAY)
-
- make_non_blocking(p.stdout)
- make_non_blocking(p.stderr)
+ if vte is None:
+ # no vte widget, will just print to the parent terminal
+ kws = {
+ 'close_fds': True,
+ 'shell': isinstance(command, (str,unicode)),
+ 'stdin': subprocess.PIPE,
+ 'stdout': subprocess.PIPE,
+ 'stderr': subprocess.PIPE,
+ }
+
+ if cwd is not None:
+ kws['cwd'] = cwd
+
+ if extra_env is not None:
+ kws['env'] = os.environ.copy()
+ kws['env'].update(extra_env)
+
+ try:
+ p = subprocess.Popen(command, **kws)
+ except OSError, e:
+ raise CommandError(str(e))
+
+ p.stdin.close()
+
+ def make_non_blocking(fd):
+ fl = fcntl.fcntl(fd, fcntl.F_GETFL)
+ fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NDELAY)
+
+ make_non_blocking(p.stdout)
+ make_non_blocking(p.stderr)
+
+ build_paused = False
+ read_set = [p.stdout, p.stderr]
+
+ while read_set:
+ # Allow the frontend to get a little time
+ while gtk.events_pending():
+ gtk.main_iteration()
+
+ rlist, wlist, xlist = select.select(read_set, [], [], 0)
+
+ if p.stdout in rlist:
+ chunk = p.stdout.read()
+ if chunk == '':
+ p.stdout.close()
+ read_set.remove(p.stdout)
+ sys.stdout.write(chunk)
+
+ if p.stderr in rlist:
+ chunk = p.stderr.read()
+ if chunk == '':
+ p.stderr.close()
+ read_set.remove(p.stderr)
+ sys.stderr.write(chunk)
+
+ # See if we should pause the current command
+ if not build_paused and self.is_build_paused():
+ os.kill(p.pid, signal.SIGSTOP)
+ build_paused = True
+ elif build_paused and not self.is_build_paused():
+ os.kill(p.pid, signal.SIGCONT)
+ build_paused = False
+
+ time.sleep(0.05)
+
+ return p.wait()
+ else:
+ # use the vte widget
+ if isinstance(command, (str, unicode)):
+ self.terminal.feed(' $ ' + command + '\n\r')
+ command = [os.environ.get('SHELL', '/bin/sh'), '-c', command]
+ else:
+ self.terminal.feed(' $ ' + ' '.join(command) + '\n\r')
- build_paused = False
- read_set = [p.stdout, p.stderr]
+ env = {}
+ if extra_env is not None:
+ env = os.environ.copy()
+ env.update(extra_env)
- while read_set:
- # Allow the frontend to get a little time
- while gtk.events_pending():
+ self.vte_fork_running = True
+ pid = self.terminal.fork_command(command=command[0], argv=command,
+ envv=env.items(), directory=cwd)
+ while self.vte_fork_running:
gtk.main_iteration()
+ return self.vte_child_exit_status
+
+ def on_vte_eof_cb(self, terminal):
+ self.vte_fork_running = False
+ self.vte_child_exit_status = -1
- rlist, wlist, xlist = select.select(read_set, [], [], 0)
-
- if p.stdout in rlist:
- chunk = p.stdout.read()
- if chunk == '':
- p.stdout.close()
- read_set.remove(p.stdout)
- # TODO: add chunk to a terminal widget
- sys.stdout.write(chunk)
-
- if p.stderr in rlist:
- chunk = p.stderr.read()
- if chunk == '':
- p.stderr.close()
- read_set.remove(p.stderr)
- # TODO: add chunk to a terminal widget
- sys.stderr.write(chunk)
-
- # See if we should pause the current command
- if not build_paused and self.is_build_paused():
- os.kill(p.pid, signal.SIGSTOP)
- build_paused = True
- elif build_paused and not self.is_build_paused():
- os.kill(p.pid, signal.SIGCONT)
- build_paused = False
-
- time.sleep(0.05)
-
- return p.wait()
+ def on_vte_child_exit_cb(self, terminal):
+ self.vte_fork_running = False
+ self.vte_child_exit_status = self.terminal.get_child_exit_status()
class SelectModuleDialog(gtk.Dialog):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]