diff --git a/gui/display.py b/gui/display.py index c2eea35..d1e71e2 100644 --- a/gui/display.py +++ b/gui/display.py @@ -16,7 +16,7 @@ # Log window. import gdb -import gui.toplevel +import gui.updatewindow import gui.startup from gi.repository import Gtk import functools @@ -26,30 +26,13 @@ import gui.events # FIXME: TO DO: # * highlight the changes -class DisplayWindow(gui.toplevel.Toplevel): +class DisplayWindow(gui.updatewindow.UpdateWindow): def __init__(self, command): - super(DisplayWindow, self).__init__() self.command = command - gui.startup.send_to_gtk(self._initialize) - self._connect_events() - # Display the data now. - self._on_event() + super(DisplayWindow, self).__init__() @in_gdb_thread - def _connect_events(self): - # FIXME - we need an event for "selected frame changed". - # ... and thread-changed - # really just pre-prompt would be good enough - gdb.events.stop.connect(self._on_event) - gui.events.frame_changed.connect(self._on_event) - - @in_gdb_thread - def _disconnect_events(self): - gdb.events.stop.disconnect(self.on_event) - gui.event.frame_changed.disconnect(self.on_event) - - @in_gdb_thread - def _on_event(self, *args): + def on_event(self): try: text = gdb.execute(self.command, to_string = True) except gdb.error as what: @@ -57,7 +40,7 @@ class DisplayWindow(gui.toplevel.Toplevel): gui.startup.send_to_gtk(lambda: self._update(text)) @in_gtk_thread - def _initialize(self): + def gtk_initialize(self): builder = gui.startup.create_builder('logwindow.xml') builder.connect_signals(self) @@ -68,12 +51,6 @@ class DisplayWindow(gui.toplevel.Toplevel): self.window.set_title('GDB "%s" @%d' % (self.command, self.number)) self.window.show() - @in_gtk_thread - def remove(self, window): - self.windows.remove(window) - if len(self.windows) == 0: - gdb.post_event(self._disconnect_events) - def _update(self, text): self.buffer.delete(self.buffer.get_start_iter(), self.buffer.get_end_iter()) diff --git a/gui/updatewindow.py b/gui/updatewindow.py new file mode 100644 index 0000000..7c0da2d --- /dev/null +++ b/gui/updatewindow.py @@ -0,0 +1,74 @@ +# Copyright (C) 2013 Tom Tromey + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Auto-updating window. + +from gui.toplevel import Toplevel +import gui.startup +from gui.startup import in_gdb_thread, in_gtk_thread +import gdb +import gui.events + +class UpdateWindow(Toplevel): + """A window that automatically updates in response to gdb changes. + + In particular, starting or stopping the inferior, or switching + frames, causes this window to be eligible for updates.""" + + def __init__(self): + super(UpdateWindow, self).__init__() + gui.startup.send_to_gtk(self.gtk_initialize) + self._connect_events() + # Display the data now. + self.on_event() + + @in_gtk_thread + def gtk_initialize(self): + """Subclasses should implement this method to do initialization + in the Gtk thread.""" + pass + + # FIXME: really ought to be passing in an event here. + @in_gdb_thread + def on_event(self): + """Subclasses should implement this method. + It is called with no arguments when the state changes.""" + pass + + @in_gdb_thread + def _connect_events(self): + # FIXME - we need an event for "selected frame changed". + # ... and thread-changed + # really just pre-prompt would be good enough + gdb.events.stop.connect(self._on_event) + gui.events.frame_changed.connect(self._on_event) + + @in_gdb_thread + def _disconnect_events(self): + gdb.events.stop.disconnect(self._on_event) + gui.event.frame_changed.disconnect(self._on_event) + + @in_gdb_thread + def _on_event(self, *args): + try: + text = gdb.execute(self.command, to_string = True) + except gdb.error as what: + text = str(what) + gui.startup.send_to_gtk(lambda: self._update(text)) + + @in_gtk_thread + def deleted(self): + gdb.post_event(self._disconnect_events) + self.destroy()