Merge lp:~iq-0/terminator/terminator into lp:terminator/trunk

Proposed by Justin Ossevoort
Status: Needs review
Proposed branch: lp:~iq-0/terminator/terminator
Merge into: lp:terminator/trunk
Diff against target: 444 lines (+70/-127)
7 files modified
terminatorlib/config.py (+1/-0)
terminatorlib/container.py (+10/-4)
terminatorlib/ipc.py (+4/-6)
terminatorlib/notebook.py (+15/-23)
terminatorlib/paned.py (+3/-2)
terminatorlib/terminator.py (+5/-13)
terminatorlib/window.py (+32/-79)
To merge this branch: bzr merge lp:~iq-0/terminator/terminator
Reviewer Review Type Date Requested Status
Stephen Boddy Needs Fixing
Review via email: mp+191196@code.launchpad.net

Description of the change

I wanted to add a simple feature: Always show tabs.

When I was investigating what needed to be done I came across a whole lot of conditionals around the use of a notebook in the terminator window. Instead of adding to the complexity of when a notebook could be present I thought it was better to simply always have a notebook present.

The reason a notebook is different from the HPaned and VPaned elements is that there can be at most 1. Any possible resources saved by not using a notebook are effectively used up by including more code to workaround the presense/absense of the notebook.

This code should handle old layouts well, but new layout will not include the 'Notebook' layer (which is effectively consolidated into 'Window'). It removes some duplicate logic about initialising a terminal. And finally it removes having to deal with what is in a Window (it's always a Notebook).

The new 'autohide_tabbar' option defaults to True, so it mimicks how Terminator now works, but setting it to false will always show the tabbar.

To post a comment you must log in.
lp:~iq-0/terminator/terminator updated
1472. By <email address hidden>

Fix first terminal split on a tab

Revision history for this message
Stephen Boddy (stephen-j-boddy) wrote :

Hi Justin. Not sure if you're still around/interested, but perhaps you have noticed I've gotten through the outstanding merges, except for yours. Because it was a bit large and scary looking mostly.

Just to be clear up front, in principle I don't have a problem with the idea, but there are issues.

I've taken a branch and been playing with it, and I straight away notice a couple of functional problems, although it is not clear to me from a quick look at your commits what exactly is causing it.

1) Set homogeneous on, and scroll button off.
2) Exit and restart.
3) Create new tab, tabs as expected, (homogeneous, no buttons)
4) Set scroll buttons on, and click close.
5) The tabs disappear! *1
6) Create new tab
7) Tabs are back with the scroll buttons
8) Set scroll buttons off, and click close
9) Again the tabs disappear
10) Create new tab
11) Tabs are back, but they're a bit messed up, and corrupted, with text overlapping *2
12) Exit window

So things that need to be fixed before proper testing is possible:
*1 Doing anything with the tab settings seems to make the tabs disappear
*2 When turning off the scroll buttons it doesn't seem to go back to homogeneous properly.

I'm probably going to put a few comments below on the Diff.

review: Needs Fixing
Revision history for this message
Stephen Boddy (stephen-j-boddy) wrote :

Some comments on the diff.

Unmerged revisions

1472. By <email address hidden>

Fix first terminal split on a tab

1471. By <email address hidden>

Add option to disable autohide on tabbar

The new global config option is called 'autohide_tabbar' and defaults to True
which mimicks the current behaviour.

Instead of adding more conditionals to whether or not to use a Notebook this
patch changes Window to always have a Notebook. This simplifies a lot of code
paths and strips a layer from alle layouts that use tabs.

It could possibly be merged even further, but these changes removed the most
obvious redundant code paths and were enough to simply add 'set_show_tabs()' on
tab open/close to make it work.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'terminatorlib/config.py'
2--- terminatorlib/config.py 2013-08-29 17:43:24 +0000
3+++ terminatorlib/config.py 2013-10-18 12:39:11 +0000
4@@ -85,6 +85,7 @@
5 'tab_position' : 'top',
6 'close_button_on_tab' : True,
7 'hide_tabbar' : False,
8+ 'autohide_tabbar' : True,
9 'scroll_tabbar' : False,
10 'homogeneous_tabbar' : True,
11 'hide_from_taskbar' : False,
12
13=== modified file 'terminatorlib/container.py'
14--- terminatorlib/container.py 2013-09-25 22:07:01 +0000
15+++ terminatorlib/container.py 2013-10-18 12:39:11 +0000
16@@ -241,16 +241,22 @@
17
18 def describe_layout(self, count, parent, global_layout, child_order):
19 """Describe our current layout"""
20- layout = {}
21 maker = Factory()
22 mytype = maker.type(self)
23 if not mytype:
24 err('unable to detemine own type. %s' % self)
25 return({})
26
27- layout['type'] = mytype
28- layout['parent'] = parent
29- layout['order'] = child_order
30+ layout = None
31+ if mytype == 'Notebook':
32+ """Merge notebook with window"""
33+ layout = global_layout[parent]
34+ count = count - 1
35+ else:
36+ layout = {}
37+ layout['type'] = mytype
38+ layout['parent'] = parent
39+ layout['order'] = child_order
40
41 if hasattr(self, 'get_position'):
42 position = self.get_position()
43
44=== modified file 'terminatorlib/ipc.py'
45--- terminatorlib/ipc.py 2012-10-30 00:11:24 +0000
46+++ terminatorlib/ipc.py 2013-10-18 12:39:11 +0000
47@@ -113,9 +113,8 @@
48 maker = Factory()
49 terminal = self.terminator.find_terminal_by_uuid(uuid)
50 window = terminal.get_toplevel()
51- root_widget = window.get_children()[0]
52- if maker.isinstance(root_widget, 'Notebook'):
53- return root_widget.uuid.urn
54+ notebook = window.get_child()
55+ return notebook.uuid.urn
56
57 @dbus.service.method(BUS_NAME)
58 def get_terminal_tab_title(self, uuid):
59@@ -123,9 +122,8 @@
60 maker = Factory()
61 terminal = self.terminator.find_terminal_by_uuid(uuid)
62 window = terminal.get_toplevel()
63- root_widget = window.get_children()[0]
64- if maker.isinstance(root_widget, "Notebook"):
65- return root_widget.get_tab_label(terminal).get_label()
66+ notebook = window.get_child()
67+ return notebook.get_tab_label(terminal).get_label()
68
69 def with_proxy(func):
70 """Decorator function to connect to the session dbus bus"""
71
72=== modified file 'terminatorlib/notebook.py'
73--- terminatorlib/notebook.py 2013-09-04 22:50:12 +0000
74+++ terminatorlib/notebook.py 2013-10-18 12:39:11 +0000
75@@ -31,12 +31,6 @@
76 gobject.type_register(Notebook)
77 self.register_signals(Notebook)
78 self.configure()
79-
80- child = window.get_child()
81- window.remove(child)
82- window.add(self)
83- self.newtab(widget=child)
84-
85 self.show_all()
86
87 def configure(self):
88@@ -51,7 +45,7 @@
89 if self.config['tab_position'] == 'hidden' or self.config['hide_tabbar']:
90 self.set_show_tabs(False)
91 else:
92- self.set_show_tabs(True)
93+ self.set_show_tabs(not self.config['autohide_tabbar'])
94 pos = getattr(gtk, 'POS_%s' % self.config['tab_position'].upper())
95 self.set_tab_pos(pos)
96
97@@ -82,8 +76,7 @@
98 return
99
100 children = layout['children']
101- if len(children) <= 1:
102- #Notebooks should have two or more children
103+ if len(children) == 0:
104 err('incorrect number of children for Notebook: %s' % layout)
105 return
106
107@@ -142,6 +135,8 @@
108 else:
109 container = maker.make('hpaned')
110
111+ self.get_toplevel().set_pos_by_ratio = True
112+
113 if not sibling:
114 sibling = maker.make('terminal')
115 sibling.set_cwd(cwd)
116@@ -167,6 +162,10 @@
117 self.show_all()
118 terminal.grab_focus()
119
120+ while gtk.events_pending():
121+ gtk.main_iteration_do(False)
122+ self.get_toplevel().set_pos_by_ratio = False
123+
124 def add(self, widget, metadata=None):
125 """Add a widget to the container"""
126 dbg('adding a new tab')
127@@ -266,9 +265,12 @@
128 self.set_tab_label_packing(widget, not self.config['scroll_tabbar'],
129 not self.config['scroll_tabbar'],
130 gtk.PACK_START)
131-
132 self.set_tab_reorderable(widget, True)
133 self.set_current_page(tabpos)
134+
135+ if self.config['autohide_tabbar'] and self.get_n_pages() > 1 and not self.get_show_tabs():
136+ self.set_show_tabs(True)
137+
138 self.show_all()
139 if maker.isinstance(widget, 'Terminal'):
140 widget.grab_focus()
141@@ -383,19 +385,9 @@
142 if not page:
143 dbg('Removing empty page: %d' % numpages)
144 self.remove_page(numpages)
145-
146- if self.get_n_pages() == 1:
147- dbg('Last page, removing self')
148- child = self.get_nth_page(0)
149- self.remove_page(0)
150- parent = self.get_parent()
151- parent.remove(self)
152- self.cnxids.remove_all()
153- parent.add(child)
154- del(self)
155- # Find the last terminal in the new parent and give it focus
156- terms = parent.get_visible_terminals()
157- terms.keys()[-1].grab_focus()
158+
159+ if self.config['autohide_tabbar'] and self.get_n_pages() < 2 and self.get_show_tabs():
160+ self.set_show_tabs(False)
161
162 class TabLabel(gtk.HBox):
163 """Class implementing a label widget for Notebook tabs"""
164
165=== modified file 'terminatorlib/paned.py'
166--- terminatorlib/paned.py 2013-09-02 14:54:07 +0000
167+++ terminatorlib/paned.py 2013-10-18 12:39:11 +0000
168@@ -39,10 +39,11 @@
169 order = None
170
171 self.remove(widget)
172+ maker = Factory()
173 if vertical:
174- container = VPaned()
175+ container = maker.make('vpaned')
176 else:
177- container = HPaned()
178+ container = maker.make('hpaned')
179
180 self.get_toplevel().set_pos_by_ratio = True
181
182
183=== modified file 'terminatorlib/terminator.py'
184--- terminatorlib/terminator.py 2013-09-04 20:59:27 +0000
185+++ terminatorlib/terminator.py 2013-10-18 12:39:11 +0000
186@@ -87,11 +87,11 @@
187 try:
188 import gnome
189 import gnome.ui
190- self.gnome_program = gnome.init(APP_NAME, APP_VERSION)
191 self.gnome_client = gnome.ui.master_client()
192 self.gnome_client.connect_to_session_manager()
193 self.gnome_client.connect('save-yourself', self.save_yourself)
194 self.gnome_client.connect('die', self.die)
195+ self.gnome_program = gnome.init(APP_NAME, APP_VERSION)
196 dbg('GNOME session support enabled and registered')
197 except (ImportError, AttributeError):
198 self.gnome_client = False
199@@ -187,15 +187,9 @@
200 def new_window(self, cwd=None):
201 """Create a window with a Terminal in it"""
202 maker = Factory()
203- window = maker.make('Window')
204- terminal = maker.make('Terminal')
205- if cwd:
206- terminal.set_cwd(cwd)
207- window.add(terminal)
208+ window = maker.make('Window', cwd=cwd)
209 window.show(True)
210- terminal.spawn_child()
211-
212- return(window, terminal)
213+ return window
214
215 def create_layout(self, layoutname):
216 """Create all the parts necessary to satisfy the specified layout"""
217@@ -261,7 +255,7 @@
218 err('invalid layout format. %s' % layout)
219 raise(ValueError)
220 dbg('Creating a window')
221- window, terminal = self.new_window()
222+ window = self.new_window()
223 if layout[windef].has_key('position'):
224 parts = layout[windef]['position'].split(':')
225 if len(parts) == 2:
226@@ -318,9 +312,7 @@
227 # Update tab position if appropriate
228 maker = Factory()
229 for window in self.windows:
230- child = window.get_child()
231- if maker.isinstance(child, 'Notebook'):
232- child.configure()
233+ window.configure()
234
235 def create_group(self, name):
236 """Create a new group"""
237
238=== modified file 'terminatorlib/window.py'
239--- terminatorlib/window.py 2013-09-04 21:02:24 +0000
240+++ terminatorlib/window.py 2013-10-18 12:39:11 +0000
241@@ -50,7 +50,7 @@
242 gobject.PARAM_READWRITE)
243 }
244
245- def __init__(self):
246+ def __init__(self, cwd=None):
247 """Class initialiser"""
248 self.terminator = Terminator()
249 self.terminator.register_window(self)
250@@ -91,6 +91,11 @@
251 self.apply_icon(icon_to_apply)
252 self.pending_set_rough_geometry_hint = False
253
254+ maker = Factory()
255+ notebook = maker.make('Notebook', window=self)
256+ gtk.Window.add(self, notebook)
257+ notebook.newtab(cwd=cwd)
258+
259 def do_get_property(self, prop):
260 """Handle gobject getting a property"""
261 if prop.name in ['term_zoomed', 'term-zoomed']:
262@@ -241,11 +246,6 @@
263 self.set_urgency_hint(False)
264 # FIXME: Cause the terminal titlebars to update here
265
266- def is_child_notebook(self):
267- """Returns True if this Window's child is a Notebook"""
268- maker = Factory()
269- return(maker.isinstance(self.get_child(), 'Notebook'))
270-
271 def tab_new(self, widget=None, debugtab=False, _param1=None, _param2=None):
272 """Make a new tab"""
273 cwd = None
274@@ -259,10 +259,6 @@
275 cwd = widget.get_cwd()
276 profile = widget.get_profile()
277
278- maker = Factory()
279- if not self.is_child_notebook():
280- dbg('Making a new Notebook')
281- notebook = maker.make('Notebook', window=self)
282 return self.get_child().newtab(debugtab, cwd=cwd, profile=profile)
283
284 def on_delete_event(self, window, event, data=None):
285@@ -397,32 +393,8 @@
286
287 def add(self, widget, metadata=None):
288 """Add a widget to the window by way of gtk.Window.add()"""
289- maker = Factory()
290- gtk.Window.add(self, widget)
291- if maker.isinstance(widget, 'Terminal'):
292- signals = {'close-term': self.closeterm,
293- 'title-change': self.title.set_title,
294- 'split-horiz': self.split_horiz,
295- 'split-vert': self.split_vert,
296- 'unzoom': self.unzoom,
297- 'tab-change': self.tab_change,
298- 'group-all': self.group_all,
299- 'ungroup-all': self.ungroup_all,
300- 'group-tab': self.group_tab,
301- 'ungroup-tab': self.ungroup_tab,
302- 'move-tab': self.move_tab,
303- 'tab-new': [self.tab_new, widget],
304- 'navigate': self.navigate_terminal}
305-
306- for signal in signals:
307- args = []
308- handler = signals[signal]
309- if isinstance(handler, list):
310- args = handler[1:]
311- handler = handler[0]
312- self.connect_child(widget, signal, handler, *args)
313-
314- widget.grab_focus()
315+ notebook = self.get_child()
316+ notebook.add(widget)
317
318 def remove(self, widget):
319 """Remove our child widget by way of gtk.Window.remove()"""
320@@ -430,6 +402,10 @@
321 self.disconnect_child(widget)
322 return(True)
323
324+ def configure(self):
325+ notebook = self.get_child()
326+ notebook.configure()
327+
328 def get_children(self):
329 """Return a single list of our child"""
330 children = []
331@@ -562,16 +538,14 @@
332 if not hasattr(self, 'cached_maker'):
333 self.cached_maker = Factory()
334 maker = self.cached_maker
335- child = self.get_child()
336+
337+ notebook = self.get_child()
338+ pagenum = notebook.get_current_page()
339+ child = notebook.get_nth_page(pagenum)
340
341 if not child:
342 return([])
343
344- # If our child is a Notebook, reset to work from its visible child
345- if maker.isinstance(child, 'Notebook'):
346- pagenum = child.get_current_page()
347- child = child.get_nth_page(pagenum)
348-
349 if maker.isinstance(child, 'Container'):
350 terminals.update(child.get_visible_terminals())
351 elif maker.isinstance(child, 'Terminal'):
352@@ -657,10 +631,6 @@
353 maker = Factory()
354 child = self.get_child()
355
356- if not maker.isinstance(child, 'Notebook'):
357- dbg('child is not a notebook, nothing to change to')
358- return
359-
360 if num == -1:
361 # Go to the next tab
362 cur = child.get_current_page()
363@@ -702,10 +672,6 @@
364 maker = Factory()
365 notebook = self.get_child()
366
367- if not maker.isinstance(notebook, 'Notebook'):
368- dbg('not in a notebook, refusing to group tab')
369- return
370-
371 pagenum = notebook.get_current_page()
372 while True:
373 group = _('Tab %d') % pagenum
374@@ -720,10 +686,6 @@
375 maker = Factory()
376 notebook = self.get_child()
377
378- if not maker.isinstance(notebook, 'Notebook'):
379- dbg('note in a notebook, refusing to ungroup tab')
380- return
381-
382 for terminal in self.get_visible_terminals():
383 terminal.set_group(None, None)
384
385@@ -732,10 +694,6 @@
386 maker = Factory()
387 notebook = self.get_child()
388
389- if not maker.isinstance(notebook, 'Notebook'):
390- dbg('not in a notebook, refusing to move tab %s' % direction)
391- return
392-
393 dbg('moving tab %s' % direction)
394 numpages = notebook.get_n_pages()
395 page = notebook.get_current_page()
396@@ -834,32 +792,27 @@
397 if not layout.has_key('children'):
398 err('layout describes no children: %s' % layout)
399 return
400- children = layout['children']
401- if len(children) != 1:
402- # We're a Window, we can only have one child
403+
404+ if len(layout['children']) == 1:
405+ child = layout['children'].values()[0]
406+ if child['type'] == 'Notebook':
407+ if not child.has_key('children'):
408+ err('layout describes no children: %s' % child)
409+ return
410+ layout = child
411+
412+ if len(layout['children']) == 0:
413+ # We're a Window, we should have at least 1 child
414 err('incorrect number of children for Window: %s' % layout)
415 return
416
417- child = children[children.keys()[0]]
418- terminal = self.get_children()[0]
419- dbg('Making a child of type: %s' % child['type'])
420- if child['type'] == 'VPaned':
421- self.split_axis(terminal, True)
422- elif child['type'] == 'HPaned':
423- self.split_axis(terminal, False)
424- elif child['type'] == 'Notebook':
425+ i = 1
426+ while i < len(layout['children']):
427 self.tab_new()
428- i = 2
429- while i < len(child['children']):
430- self.tab_new()
431- i = i + 1
432- elif child['type'] == 'Terminal':
433- pass
434- else:
435- err('unknown child type: %s' % child['type'])
436- return
437+ i = i + 1
438
439- self.get_children()[0].create_layout(child)
440+ notebook = self.get_child()
441+ notebook.create_layout(layout)
442
443 class WindowTitle(object):
444 """Class to handle the setting of the window title"""