Fixes zero-sized terminals after rotate

This commit is contained in:
Stephen Boddy 2016-11-23 06:10:25 +01:00
parent 6a430ca05b
commit 01712503a0
2 changed files with 61 additions and 25 deletions

View File

@ -403,8 +403,17 @@ class Paned(Container):
"""We don't want focus, we want a Terminal to have it""" """We don't want focus, we want a Terminal to have it"""
self.get_child1().grab_focus() self.get_child1().grab_focus()
def rotate(self, widget, clockwise): def rotate_recursive(self, parent, w, h, clockwise):
"""Default rotation. This should be implemented by subclasses""" """
Recursively rotate "self" into a new paned that'll have "w" x "h" size. Attach it to "parent".
As discussed in LP#1522542, we should build up the new layout (including the separator positions)
in a single step. We can't rely on Gtk+ computing the allocation sizes yet, so we have to do the
computation ourselves and carry the resulting paned sizes all the way down the widget tree.
"""
maker = Factory()
handle_size = self.get_handlesize()
if isinstance(self, HPaned): if isinstance(self, HPaned):
container = VPaned() container = VPaned()
reverse = not clockwise reverse = not clockwise
@ -413,17 +422,34 @@ class Paned(Container):
reverse = clockwise reverse = clockwise
container.ratio = self.ratio container.ratio = self.ratio
self.get_parent().replace(self, container)
children = self.get_children() children = self.get_children()
if reverse: if reverse:
container.ratio = 1 - container.ratio container.ratio = 1 - container.ratio
children.reverse() children.reverse()
for child in children: if isinstance(self, HPaned):
self.remove(child) w1 = w2 = w
container.add(child) h1 = pos = self.position_by_ratio(h, handle_size, container.ratio)
h2 = max(h - h1 - handle_size, 0)
else:
h1 = h2 = h
w1 = pos = self.position_by_ratio(w, handle_size, container.ratio)
w2 = max(w - w1 - handle_size, 0)
container.set_pos(pos)
parent.add(container)
if maker.isinstance(children[0], 'Terminal'):
children[0].get_parent().remove(children[0])
container.add(children[0])
else:
children[0].rotate_recursive(container, w1, h1, clockwise)
if maker.isinstance(children[1], 'Terminal'):
children[1].get_parent().remove(children[1])
container.add(children[1])
else:
children[1].rotate_recursive(container, w2, h2, clockwise)
def new_size(self, widget, allocation): def new_size(self, widget, allocation):
if self.get_toplevel().set_pos_by_ratio: if self.get_toplevel().set_pos_by_ratio:
@ -431,13 +457,26 @@ class Paned(Container):
else: else:
self.set_position(self.get_position()) self.set_position(self.get_position())
def position_by_ratio(self, total_size, handle_size, ratio):
non_separator_size = max(total_size, handle_size, 0)
ratio = min(max(ratio, 0.0), 1.0)
return int(round(non_separator_size * ratio))
def ratio_by_position(self, total_size, handle_size, position):
non_separator_size = max(total_size, handle_size, 0)
if non_separator_size == 0:
return None
position = min(max(position, 0), non_separator_size)
return float(position) / float(non_separator_size)
def set_position_by_ratio(self): def set_position_by_ratio(self):
handle_size = handle_size = self.get_handlesize() handle_size = handle_size = self.get_handlesize()
self.set_pos(int((self.ratio*self.get_length())-(handle_size/2.0))) self.set_pos(self.position_by_ratio(self.get_length(), self.get_handlesize(), self.ratio))
def set_position(self, pos): def set_position(self, pos):
handle_size = handle_size = self.get_handlesize() newratio = self.ratio_by_position(self.get_length(), self.get_handlesize(), pos)
self.ratio = float(pos + (handle_size/2.0)) / self.get_length() if newratio is not None:
self.ratio = newratio
self.set_pos(pos) self.set_pos(pos)
class HPaned(Paned, Gtk.HPaned): class HPaned(Paned, Gtk.HPaned):

View File

@ -533,8 +533,6 @@ class Window(Container, Gtk.Window):
"""Rotate children in this window""" """Rotate children in this window"""
self.set_pos_by_ratio = True self.set_pos_by_ratio = True
maker = Factory() maker = Factory()
# collect all paned children in breadth-first order
paned = []
child = self.get_child() child = self.get_child()
# If our child is a Notebook, reset to work from its visible child # If our child is a Notebook, reset to work from its visible child
@ -543,19 +541,18 @@ class Window(Container, Gtk.Window):
child = child.get_nth_page(pagenum) child = child.get_nth_page(pagenum)
if maker.isinstance(child, 'Paned'): if maker.isinstance(child, 'Paned'):
paned.append(child) parent = child.get_parent()
for p in paned: # Need to get the allocation before we remove the child,
for child in p.get_children(): # otherwise _sometimes_ we get incorrect values.
if child not in paned and maker.isinstance(child, 'Paned'): alloc = child.get_allocation()
paned.append(child) parent.remove(child)
# then propagate the rotation child.rotate_recursive(parent, alloc.width, alloc.height, clockwise)
for p in paned:
p.rotate(widget, clockwise)
self.show_all()
self.show_all()
while Gtk.events_pending(): while Gtk.events_pending():
Gtk.main_iteration_do(False) Gtk.main_iteration_do(False)
widget.grab_focus() widget.grab_focus()
self.set_pos_by_ratio = False self.set_pos_by_ratio = False
def get_visible_terminals(self): def get_visible_terminals(self):