diff --git a/gertty/app.py b/gertty/app.py
index db1ce89..399d48d 100644
--- a/gertty/app.py
+++ b/gertty/app.py
@@ -16,6 +16,7 @@
 import argparse
 import logging
 import os
+import Queue
 import sys
 import threading
 import webbrowser
@@ -227,7 +228,12 @@ class App(object):
         widget = self.loop.widget
         while isinstance(widget, urwid.Overlay):
             widget = widget.contents[0][0]
-        widget.refresh()
+        try:
+            while True:
+                event = self.sync.result_queue.get(0)
+                widget.refresh(event)
+        except Queue.Empty:
+            pass
 
     def popup(self, widget,
               relative_width=50, relative_height=25,
diff --git a/gertty/sync.py b/gertty/sync.py
index e758a7a..fdbb8b9 100644
--- a/gertty/sync.py
+++ b/gertty/sync.py
@@ -78,6 +78,38 @@ class MultiQueue(object):
         finally:
             self.condition.release()
 
+class UpdateEvent(object):
+    def updateRelatedChanges(self, session, change):
+        related_change_keys = set()
+        related_change_keys.add(change.key)
+        for revision in change.revisions:
+            parent = session.getRevisionByCommit(revision.parent)
+            if parent:
+                related_change_keys.add(parent.change.key)
+            for child in session.getRevisionsByParent(revision.commit):
+                related_change_keys.add(child.change.key)
+        self.related_change_keys = related_change_keys
+
+class ProjectAddedEvent(UpdateEvent):
+    def __init__(self, project):
+        self.project_key = project.key
+
+class ChangeAddedEvent(UpdateEvent):
+    def __init__(self, change):
+        self.project_key = change.project.key
+        self.change_key = change.key
+        self.related_change_keys = set()
+        self.review_flag_changed = True
+        self.status_changed = True
+
+class ChangeUpdatedEvent(UpdateEvent):
+    def __init__(self, change):
+        self.project_key = change.project.key
+        self.change_key = change.key
+        self.related_change_keys = set()
+        self.review_flag_changed = False
+        self.status_changed = False
+
 class Task(object):
     def __init__(self, priority=NORMAL_PRIORITY):
         self.log = logging.getLogger('gertty.sync')
@@ -85,6 +117,7 @@ class Task(object):
         self.succeeded = None
         self.event = threading.Event()
         self.tasks = []
+        self.results = []
 
     def complete(self, success):
         self.succeeded = success
@@ -127,7 +160,9 @@ class SyncProjectListTask(Task):
 
             for name in remote_keys-local_keys:
                 p = remote[name]
-                session.createProject(name, description=p.get('description', ''))
+                project = session.createProject(name,
+                                                description=p.get('description', ''))
+                self.results.append(ProjectAddedEvent(project))
 
 class SyncSubscribedProjectBranchesTask(Task):
     def __repr__(self):
@@ -327,8 +362,14 @@ class SyncChangeTask(Task):
                                               remote_change['subject'], created,
                                               updated, remote_change['status'],
                                               topic=remote_change.get('topic'))
+                result = ChangeAddedEvent(change)
+            else:
+                result = ChangeUpdatedEvent(change)
+            self.results.append(result)
             change.owner = account
-            change.status = remote_change['status']
+            if change.status != remote_change['status']:
+                change.status = remote_change['status']
+                result.status_changed = True
             change.subject = remote_change['subject']
             change.updated = dateutil.parser.parse(remote_change['updated'])
             change.topic = remote_change.get('topic')
@@ -367,6 +408,7 @@ class SyncChangeTask(Task):
                     sync.submitTask(SyncChangeByCommitTask(revision.parent, self.priority))
                     self.log.debug("Change %s revision %s needs parent commit %s synced" %
                                    (change.id, remote_revision['_number'], revision.parent))
+                result.updateRelatedChanges(session, change)
                 remote_comments_data = remote_revision['_gertty_remote_comments_data']
                 for remote_file, remote_comments in remote_comments_data.items():
                     for remote_comment in remote_comments:
@@ -499,7 +541,9 @@ class SyncChangeTask(Task):
             if not user_voted:
                 # Only consider changing the reviewed state if we don't have a vote
                 if new_revision or new_message:
-                    change.reviewed = False
+                    if not change.reviewed:
+                        change.reviewed = False
+                        result.review_flag_changed = True
         for url, refs in fetches.items():
             self.log.debug("Fetching from %s with refs %s", url, refs)
             try:
@@ -781,6 +825,7 @@ class Sync(object):
         self.app = app
         self.log = logging.getLogger('gertty.sync')
         self.queue = MultiQueue([HIGH_PRIORITY, NORMAL_PRIORITY, LOW_PRIORITY])
+        self.result_queue = Queue.Queue()
         self.session = requests.Session()
         if self.app.config.auth_type == 'basic':
             authclass = requests.auth.HTTPBasicAuth
@@ -838,6 +883,8 @@ class Sync(object):
             self.app.status.update(error=True, refresh=False)
         self.offline = False
         self.app.status.update(offline=False, refresh=False)
+        for r in task.results:
+            self.result_queue.put(r)
         os.write(pipe, 'refresh\n')
         return None
 
diff --git a/gertty/view/change.py b/gertty/view/change.py
index 096e15f..028d466 100644
--- a/gertty/view/change.py
+++ b/gertty/view/change.py
@@ -14,6 +14,7 @@
 # under the License.
 
 import datetime
+import logging
 
 import urwid
 
@@ -415,6 +416,7 @@ class ChangeView(urwid.WidgetWrap):
 
     def __init__(self, app, change_key):
         super(ChangeView, self).__init__(urwid.Pile([]))
+        self.log = logging.getLogger('gertty.view.change')
         self.app = app
         self.change_key = change_key
         self.revision_rows = {}
@@ -497,7 +499,15 @@ class ChangeView(urwid.WidgetWrap):
             if not succeeded:
                 raise gertty.view.DisplayError("Git commits not present in local repository")
 
-    def refresh(self):
+    def refresh(self, event=None):
+        if event and not ((isinstance(event, sync.ChangeAddedEvent) and
+                           self.change_key in event.related_change_keys)
+                          or
+                          (isinstance(event, sync.ChangeUpdatedEvent) and
+                           self.change_key in event.related_change_keys)):
+            self.log.debug("Ignoring refresh change due to event %s" % (event,))
+            return
+        self.log.debug("Refreshing change due to event %s" % (event,))
         change_info = []
         with self.app.db.getSession() as session:
             change = session.getChange(self.change_key)
diff --git a/gertty/view/change_list.py b/gertty/view/change_list.py
index fb39f74..396ffd9 100644
--- a/gertty/view/change_list.py
+++ b/gertty/view/change_list.py
@@ -14,6 +14,7 @@
 # under the License.
 
 import datetime
+import logging
 import urwid
 
 from gertty import keymap
@@ -115,8 +116,10 @@ class ChangeListView(urwid.WidgetWrap):
              "Reverse the sort")
             ]
 
-    def __init__(self, app, query, query_desc=None, unreviewed=False):
+    def __init__(self, app, query, query_desc=None, project_key=None,
+                 unreviewed=False):
         super(ChangeListView, self).__init__(urwid.Pile([]))
+        self.log = logging.getLogger('gertty.view.change_list')
         self.app = app
         self.query = query
         self.query_desc = query_desc or query
@@ -124,7 +127,8 @@ class ChangeListView(urwid.WidgetWrap):
         self.change_rows = {}
         self.listbox = urwid.ListBox(urwid.SimpleFocusListWalker([]))
         self.display_owner = self.display_project = self.display_updated = True
-        if '_project_key' in query:
+        self.project_key = project_key
+        if project_key is not None:
             self.display_project = False
         self.sort_by = 'number'
         self.reverse = False
@@ -138,7 +142,20 @@ class ChangeListView(urwid.WidgetWrap):
         self._w.contents.append((self.listbox, ('weight', 1)))
         self._w.set_focus(3)
 
-    def refresh(self):
+    def refresh(self, event=None):
+        if event and not (('_project_key' in self.query and
+                           isinstance(event, sync.ChangeAddedEvent) and
+                           self.project_key == event.project_key)
+                          or
+                          ('_project_key' not in self.query and
+                           isinstance(event, sync.ChangeAddedEvent))
+                          or
+                          (isinstance(event, sync.ChangeUpdatedEvent) and
+                           event.change_key in self.change_rows.keys())):
+            self.log.debug("Ignoring refresh change list due to event %s" % (event,))
+            return
+        self.log.debug("Refreshing change list due to event %s" % (event,))
+
         unseen_keys = set(self.change_rows.keys())
         with self.app.db.getSession() as session:
             lst = session.getChanges(self.query, self.unreviewed,
diff --git a/gertty/view/diff.py b/gertty/view/diff.py
index 2d9f9cb..9630a7d 100644
--- a/gertty/view/diff.py
+++ b/gertty/view/diff.py
@@ -20,6 +20,7 @@ import urwid
 from gertty import keymap
 from gertty import mywid
 from gertty import gitrepo
+from gertty import sync
 
 class PatchsetDialog(urwid.WidgetWrap):
     signals = ['ok', 'cancel']
@@ -340,9 +341,17 @@ class BaseDiffView(urwid.WidgetWrap):
     def makeFileHeader(self, diff, comment_lists):
         raise NotImplementedError
 
-    def refresh(self):
+    def refresh(self, event=None):
+        if event and not ((isinstance(event, sync.ChangeAddedEvent) and
+                           self.change_key in event.related_change_keys)
+                          or
+                          (isinstance(event, sync.ChangeUpdatedEvent) and
+                           self.change_key in event.related_change_keys)):
+            #self.log.debug("Ignoring refresh diff due to event %s" % (event,))
+            return
+        #self.log.debug("Refreshing diff due to event %s" % (event,))
         #TODO
-        pass
+        return
 
     def keypress(self, size, key):
         old_focus = self.listbox.focus
diff --git a/gertty/view/project_list.py b/gertty/view/project_list.py
index 221bed7..5fa1eab 100644
--- a/gertty/view/project_list.py
+++ b/gertty/view/project_list.py
@@ -13,6 +13,7 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
+import logging
 import urwid
 
 from gertty import keymap
@@ -82,6 +83,7 @@ class ProjectListView(urwid.WidgetWrap):
 
     def __init__(self, app):
         super(ProjectListView, self).__init__(urwid.Pile([]))
+        self.log = logging.getLogger('gertty.view.project_list')
         self.app = app
         self.unreviewed = True
         self.subscribed = True
@@ -95,7 +97,17 @@ class ProjectListView(urwid.WidgetWrap):
         self._w.contents.append((self.listbox, ('weight', 1)))
         self._w.set_focus(3)
 
-    def refresh(self):
+    def refresh(self, event=None):
+        if event and not (isinstance(event, sync.ProjectAddedEvent)
+                          or
+                          isinstance(event, sync.ChangeAddedEvent)
+                          or
+                          (isinstance(event, sync.ChangeUpdatedEvent) and
+                           (event.status_changed or event.review_flag_changed))):
+            self.log.debug("Ignoring refresh project list due to event %s" % (event,))
+            return
+        self.log.debug("Refreshing project list due to event %s" % (event,))
+
         if self.subscribed:
             self.title = u'Subscribed projects'
             if self.unreviewed:
@@ -134,7 +146,7 @@ class ProjectListView(urwid.WidgetWrap):
         self.app.changeScreen(view_change_list.ChangeListView(
                 self.app,
                 "_project_key:%s %s" % (project_key, self.app.config.project_change_list_query),
-                project_name, unreviewed=True))
+                project_name, project_key=None, unreviewed=True))
 
     def keypress(self, size, key):
         r = super(ProjectListView, self).keypress(size, key)