[meld] filediff: Add a new callback locking helper and use for scrolling
- From: Kai Willadsen <kaiw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [meld] filediff: Add a new callback locking helper and use for scrolling
- Date: Tue, 25 Apr 2017 01:57:34 +0000 (UTC)
commit 854e79d732f8b0819ab392b81fa3954858d9339b
Author: Kai Willadsen <kai willadsen gmail com>
Date: Mon Apr 17 08:52:01 2017 +1000
filediff: Add a new callback locking helper and use for scrolling
The main benefit of this, other than looking nicer in use, is that we're
doing our locking in a try/finally, so tracebacks in the scrolling code
won't leave us with a permanently held scroll lock.
meld/filediff.py | 39 +++++++++++++++++++++++++++++----------
1 files changed, 29 insertions(+), 10 deletions(-)
---
diff --git a/meld/filediff.py b/meld/filediff.py
index 8a8c877..10d3e19 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -54,6 +54,33 @@ def with_focused_pane(function):
return wrap_function
+def with_scroll_lock(lock_attr):
+ """Decorator for locking a callback based on an instance attribute
+
+ This is used when scrolling panes. Since a scroll event in one pane
+ causes us to set the scroll position in other panes, we need to
+ stop these other panes re-scrolling the initial one.
+
+ Unlike a threading-style lock, this decorator discards any calls
+ that occur while the lock is held, rather than queuing them.
+
+ :param lock_attr: The instance attribute used to lock access
+ """
+ def wrap(function):
+ @functools.wraps(function)
+ def wrap_function(locked, *args, **kwargs):
+ if getattr(locked, lock_attr, False) or locked._scroll_lock:
+ return
+
+ try:
+ setattr(locked, lock_attr, True)
+ return function(locked, *args, **kwargs)
+ finally:
+ setattr(locked, lock_attr, False)
+ return wrap_function
+ return wrap
+
+
MASK_SHIFT, MASK_CTRL = 1, 2
PANE_LEFT, PANE_RIGHT = -1, +1
@@ -1633,23 +1660,16 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
buf = self.textbuffer[index]
self.set_buffer_editable(buf, not button.get_active())
+ @with_scroll_lock('_sync_hscroll_lock')
def _sync_hscroll(self, adjustment):
- if self._sync_hscroll_lock or self._scroll_lock:
- return
-
- self._sync_hscroll_lock = True
val = adjustment.get_value()
for sw in self.scrolledwindow[:self.num_panes]:
adj = sw.get_hadjustment()
if adj is not adjustment:
adj.set_value(val)
- self._sync_hscroll_lock = False
+ @with_scroll_lock('_sync_vscroll_lock')
def _sync_vscroll(self, adjustment, master):
- if self._sync_vscroll_lock or self._scroll_lock:
- return
-
- self._sync_vscroll_lock = True
SYNCPOINT = 0.5
# Middle of the screen, in buffer coords
@@ -1715,7 +1735,6 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
# If we just changed the central bar, make it the master
if i == 1:
master, target_line = 1, other_line
- self._sync_vscroll_lock = False
for lm in self.linkmap:
lm.queue_draw()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]