diff --git a/NOTES b/NOTES index b1d8142..0fb28e4 100644 --- a/NOTES +++ b/NOTES @@ -24,6 +24,11 @@ A few notes on gdb improvements that would help the GUI: documented. And, "set font" prints a line unconditionally, see bug 14513. +* Trying to add a set/show prefix is hard. I had to add two separate + commands and then couldn't get "set gui" (without further args) to + work the way that it does in gdb. Maybe it should just invoke + "help set gui"? + ================================================================ Windows diff --git a/gui/display.py b/gui/display.py index 77b9c5d..1325cca 100644 --- a/gui/display.py +++ b/gui/display.py @@ -32,7 +32,7 @@ class DisplayWindow(gui.updatewindow.UpdateWindow): self.command = command self.diff = diff self.last_text = None - super(DisplayWindow, self).__init__() + super(DisplayWindow, self).__init__('display') @in_gdb_thread def on_event(self): @@ -56,7 +56,7 @@ class DisplayWindow(gui.updatewindow.UpdateWindow): if self.diff: self.tag = self.buffer.create_tag('new', foreground = 'red') - self.window.set_title('GDB "%s" @%d' % (self.command, self.number)) + self.update_title() self.window.show() def _update(self, text): diff --git a/gui/gdbutil.py b/gui/gdbutil.py index c317a68..b6f4f4a 100644 --- a/gui/gdbutil.py +++ b/gui/gdbutil.py @@ -16,8 +16,25 @@ # Little gdb utilities. import gdb +import gdb.prompt + from gui.startup import in_gdb_thread +gui_prompt_substitutions = dict(gdb.prompt.prompt_substitutions) + +_current_window_for_prompt = None + +def _prompt_window(attr): + if _current_window_for_prompt is None: + return '' + if attr is None: + return '' + if not hasattr(_current_window_for_prompt, attr): + return None + return str(getattr(_current_window_for_prompt, attr)) + +gui_prompt_substitutions['W'] = _prompt_window + @in_gdb_thread def is_running(): """Return True if the inferior is running.""" @@ -26,3 +43,31 @@ def is_running(): if gdb.selected_thread() and gdb.selected_thread().is_running(): return True return False + +# GDB's API should do this... +def substitute_prompt_with_window(prompt, window): + global _current_window_for_prompt + global gui_prompt_substitutions + save = gdb.prompt.prompt_substitutions + _current_window_for_prompt = window + gdb.prompt.prompt_substitutions = gui_prompt_substitutions + try: + result = gdb.prompt.substitute_prompt(prompt) + finally: + gdb.prompt.prompt_substitutions = save + _current_window_for_prompt = None + return result + +# GDB's API should do this... +def prompt_help_with_window(window): + global _current_window_for_prompt + global gui_prompt_substitutions + save = gdb.prompt.prompt_substitutions + _current_window_for_prompt = window + gdb.prompt.prompt_substitutions = gui_prompt_substitutions + try: + result = gdb.prompt.prompt_help() + finally: + gdb.prompt.prompt_substitutions = save + _current_window_for_prompt = None + return result diff --git a/gui/logwindow.py b/gui/logwindow.py index a46b1eb..9a74ce0 100644 --- a/gui/logwindow.py +++ b/gui/logwindow.py @@ -27,9 +27,13 @@ default_log_window = None class LogWindow(gui.toplevel.Toplevel): def __init__(self): - super(LogWindow, self).__init__() + super(LogWindow, self).__init__('log') global default_log_window + if default_log_window is not None: + default_log_window.default = '' default_log_window = self + # For the window title. + self.default = ' [Default]' gui.startup.send_to_gtk(self._initialize) def _initialize(self): @@ -55,6 +59,7 @@ class LogWindow(gui.toplevel.Toplevel): for window in gui.toplevel.state.windows(): if isinstance(window, LogWindow): default_log_window = window + window.default = ' [Default]' window.update_title() break @@ -68,10 +73,3 @@ class LogWindow(gui.toplevel.Toplevel): @in_gtk_thread def set_font(self, pango_font): self.view.modify_font(pango_font) - - @in_gtk_thread - def update_title(self): - title = 'GDB Log @%d' % self.number - if self is default_log_window: - title += ' [Default]' - self.window.set_title(title) diff --git a/gui/params.py b/gui/params.py index c16e042..324b129 100644 --- a/gui/params.py +++ b/gui/params.py @@ -16,6 +16,7 @@ # Parameters import gdb +import gdb.prompt import gui.startup import gui.storage import gui.toplevel @@ -30,6 +31,13 @@ class _SetBase(gdb.Command): super(_SetBase, self).__init__('set gui', gdb.COMMAND_NONE, prefix = True) +class _SetTitleBase(gdb.Command): + """Generic command for modifying GUI window titles.""" + + def __init__(self): + super(_SetTitleBase, self).__init__('set gui title', gdb.COMMAND_NONE, + prefix = True) + class _ShowBase(gdb.Command): """Generic command for showing GUI settings.""" @@ -37,6 +45,13 @@ class _ShowBase(gdb.Command): super(_ShowBase, self).__init__('show gui', gdb.COMMAND_NONE, prefix = True) +class _ShowTitleBase(gdb.Command): + """Generic command for showing GUI window titles.""" + + def __init__(self): + super(_ShowTitleBase, self).__init__('show gui title', gdb.COMMAND_NONE, + prefix = True) + class _Theme(gdb.Parameter): # Silly gdb requirement. "" @@ -107,7 +122,45 @@ class _Font(gdb.Parameter): self.storage.set('font', self.value) return "" +title_params = {} + +class _Title(gdb.Parameter): + # Silly gdb requirement. + "" + + def __init__(self, name, default): + title_params[name] = self + self.name = name + self.set_doc = "Set the %s window title format." % self.name + self.show_doc = "Show the %s window title format." % self.name + self.manager = GtkSource.StyleSchemeManager.get_default() + self.storage = gui.storage.storage_manager + super(_Title, self).__init__('gui title %s' % name, gdb.COMMAND_NONE, + gdb.PARAM_STRING) + val = self.storage.get('title-%s' % name) + if val is not None: + self.value = val + else: + self.value = default + + @in_gdb_thread + def get_show_string(self, pvalue): + return "The current title format for the %s is: %s" % (self.name, + self.value) + + @in_gdb_thread + def get_set_string(self): + # gui.toplevel.state.set_font(self.value) + self.storage.set('title-%s' % self.name, self.value) + return "" + _SetBase() +_SetTitleBase() _ShowBase() +_ShowTitleBase() source_theme = _Theme() font_manager = _Font() + +_Title('source', '\\W{basename} [GDB Source @\\W{number}]') +_Title('display', '\\W{command} [GDB Display @\\W{number}]') +_Title('log', '[GDB Log @\\W{number}]\\W{default}') diff --git a/gui/source.py b/gui/source.py index d84285c..26c49d7 100644 --- a/gui/source.py +++ b/gui/source.py @@ -19,7 +19,6 @@ import gdb import gui import gui.updatewindow from gui.invoker import Invoker -from gui.toplevel import Toplevel import gui.startup from gui.startup import in_gdb_thread, in_gtk_thread import gui.toplevel @@ -197,7 +196,7 @@ class SourceWindow(gui.updatewindow.UpdateWindow): return GdkPixbuf.Pixbuf.new_from_file(path) def __init__(self): - super(SourceWindow, self).__init__() + super(SourceWindow, self).__init__('source') gdb.events.cont.connect(self._on_cont_event) @in_gtk_thread @@ -233,7 +232,7 @@ class SourceWindow(gui.updatewindow.UpdateWindow): lru_handler.add(self) - self.window.set_title('GDB Source @%d' % self.number) + self.update_title() self.window.show() @in_gtk_thread @@ -281,9 +280,9 @@ class SourceWindow(gui.updatewindow.UpdateWindow): if buff is not None: old_buffer = self.view.get_buffer() self.view.set_buffer(buff) - # Might be good to let the user pick the format... - self.window.set_title('%s - GDB Source @%d' - % (os.path.basename(srcfile), self.number)) + self.fullname = srcfile + self.basename = os.path.basename(srcfile) + self.update_title() buffer_manager.release_buffer(old_buffer) GObject.idle_add(self._do_scroll, buff, srcline - 1) # self.view.scroll_to_iter(buff.get_iter_at_line(srcline), 0.0) diff --git a/gui/toplevel.py b/gui/toplevel.py index 7e0333e..fb499e0 100644 --- a/gui/toplevel.py +++ b/gui/toplevel.py @@ -16,8 +16,11 @@ # Toplevel handling. import gdb +import gui.gdbutil +import gui.params import gui.startup import threading + from gi.repository import Pango from gui.startup import in_gdb_thread, in_gtk_thread @@ -77,10 +80,11 @@ class _ToplevelState(object): state = _ToplevelState() class Toplevel(object): - def __init__(self): + def __init__(self, window_type): state.add(self) # The subclass must set this. self.window = None + self.window_type = window_type def destroy(self): state.remove(self) @@ -95,3 +99,9 @@ class Toplevel(object): # Subclasses can override this to be notified when the user # changes the font. pass + + @in_gtk_thread + def update_title(self): + fmt = gui.params.title_params[self.window_type].value + title = gui.gdbutil.substitute_prompt_with_window(fmt, self) + self.window.set_title(title) diff --git a/gui/updatewindow.py b/gui/updatewindow.py index f58f939..31b9af9 100644 --- a/gui/updatewindow.py +++ b/gui/updatewindow.py @@ -27,8 +27,8 @@ class UpdateWindow(Toplevel): 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__() + def __init__(self, window_type): + super(UpdateWindow, self).__init__(window_type) gui.startup.send_to_gtk(self.gtk_initialize) self._connect_events() # Display the data now.