This is the mail archive of the insight@sources.redhat.com mailing list for the Insight project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch: multiple source windows


I've cleaned up the multiple source window support a bit.
With this patch, source windows are chosen roughly LRU.

This patch isn't perfect yet:

* The logic exists to support "fixing" a window (letting the user
  indicate that a window should not be included in the search for the
  next usable window), but there is no GUI for this yet.

* The only way to get a new source window is via the right button menu
  Eventually I think all the existing source windows should appear on
  the View menu, as should an "Open Another Source Window" command.

* If you do something like "fini", the most recently used source
  window will still display an orange highlight (as if you had
  selected the corresponding frame via the stack window) even though
  that frame no longer appears on the stack.  This looks hard to fix.

* While I'm not entirely happy with the number of new methods I had to
  add to make this work, I think it is pretty clear that the src*
  widgets already have way too many public methods.  Adding a few more
  doesn't seem too bad in that light.

I still think this patch is a good start and should go in.  The "Open
Another Source Window" command is already on the right button menu;
this patch just makes that code more useful.

My preferred mode for GUI patches is to do them in stages.  For
instance, I'd like to fix up the View menu, but I'd prefer to do that
as a followup patch.  If you'd prefer complete, finished patches, I
can do that, too.

2000-11-30  Tom Tromey  <tromey@cygnus.com>

	* bpwin.itb (BpWin::goto_bp): Handle multiple source windows.
	* srctextwin.itb (SrcTextWin::get_file): New method.
	(SrcTextWin::set_tag_to_stack): New method.
	* srctextwin.ith (get_file): Declare.
	* srcwin.ith (update_hook_init, window_list, pc_window): New
	common variables.
	(_choose_window, choose_and_update, is_fixed, get_file): Declare.
	* srcwin.itb (SrcWin::_choose_window): New method.
	(SrcWin::choose_and_update): Likewise.
	(SrcWin::_update): Renamed from update.  Now private.  Added `loc'
	argument.
	(SrcWin::get_file): New method.
	(SrcWin::is_fixed): Likewise.
	(SrcWin::constructor): Only add update hook once.  Append this
	object to window list.
	(SrcWin::destructor): Don't add update hook.  Remove this object
	from window list.  Clear pc_window if necessary.
	(SrcWin::get_top): New method.
	(SrcWin::_set_tag_to_stack): New method.
	(SrcWin::choose_and_display): New method.

Tom


Index: srctextwin.itb
===================================================================
RCS file: /cvs/src/src/gdb/gdbtk/library/srctextwin.itb,v
retrieving revision 1.13
diff -u -r1.13 srctextwin.itb
--- srctextwin.itb	2000/11/30 22:49:46	1.13
+++ srctextwin.itb	2000/11/30 23:02:53
@@ -692,6 +692,7 @@
   }
   
 }
+
 # ------------------------------------------------------------------
 #  METHOD:  handle_set_hook - Handle changes in the gdb variables
 #           changed through the "set" gdb command.
@@ -1139,6 +1140,22 @@
 }
 
 # ------------------------------------------------------------------
+# METHOD: set_tag - update tag to STACK without making other changes
+# ------------------------------------------------------------------
+body SrcTextWin::set_tag_to_stack {} {
+  foreach window [list $twin $bwin] {
+    if {$window == ""} then {
+      continue
+    }
+    foreach {start end} [$window tag ranges PC_TAG] {
+      $window tag remove PC_TAG $start $end
+      $window tag add STACK_TAG $start $end
+    }
+  }
+  set current(tag) STACK_TAG
+}
+
+# ------------------------------------------------------------------
 # METHOD: location - display a location in a file
 # ------------------------------------------------------------------
 body SrcTextWin::location {tagname filename funcname line addr pc_addr lib} {
@@ -1555,7 +1572,7 @@
 }
 
 # ------------------------------------------------------------------
-#  METHOD:  report_current_location  
+#  METHOD:  report_source_location
 #    
 #    This function reports the "current" location in the source
 #    window, where current means what gdb_loc would return, if 
@@ -2726,6 +2743,13 @@
 }
 
 # ------------------------------------------------------------------
+#  METHOD:  get_file - Return name of current file.
+# ------------------------------------------------------------------
+body SrcTextWin::get_file {} {
+  return $current(filename)
+}
+
+# ------------------------------------------------------------------
 #  METHOD:  clear_file - Clear out state so that user may load
 #              new executable. For the SrcTextWin class, this means:
 #
@@ -2801,5 +2825,3 @@
     }
   }
 }
-
-
Index: srctextwin.ith
===================================================================
RCS file: /cvs/src/src/gdb/gdbtk/library/srctextwin.ith,v
retrieving revision 1.6
diff -u -r1.6 srctextwin.ith
--- srctextwin.ith	2000/11/30 22:49:46	1.6
+++ srctextwin.ith	2000/11/30 23:02:53
@@ -86,6 +86,8 @@
     method do_thread_bp {listbox}
     method test_get {var}
     method clear_file {}
+    method get_file {}
+    method set_tag_to_stack {}
   }
 
   protected {
Index: srcwin.itb
===================================================================
RCS file: /cvs/src/src/gdb/gdbtk/library/srcwin.itb,v
retrieving revision 1.4
diff -u -r1.4 srcwin.itb
--- srcwin.itb	2000/11/30 22:49:46	1.4
+++ srcwin.itb	2000/11/30 23:02:54
@@ -19,26 +19,29 @@
   debug "$args"
   eval itk_initialize $args
   set top [winfo toplevel $itk_interior]
-  
+
   _update_title ""
-  
+
   # On Windows, create a sizebox.
   if {$::tcl_platform(platform) == "windows"} {
     ide_sizebox $itk_interior.sizebox
   }
-  
+
   set Tracing [pref get gdb/mode]
   set current(filename) ""
-  
+
   if {[catch {_build_win} mssg]} {
     dbug E "_build_win returned: $::errorInfo"
   }
-  
+
   # add special delete handler
   wm protocol $top WM_DELETE_WINDOW "[code $this _exit]"
-  
+
   # add hooks
-  add_hook gdb_update_hook "$this update"
+  if {! $update_hook_init} then {
+    set update_hook_init 1
+    add_hook gdb_update_hook "SrcWin::choose_and_update"
+  }
   add_hook gdb_busy_hook "$this busy"
   add_hook gdb_idle_hook "$this idle"
   add_hook gdb_no_inferior_hook "$this no_inferior"
@@ -48,6 +51,8 @@
   after idle "
       update idletasks
       $this sizeWinByChild toolbar"
+
+  lappend window_list $this
 }
 
 # ------------------------------------------------------------------
@@ -55,13 +60,16 @@
 # ------------------------------------------------------------------
 body SrcWin::destructor {} {
   debug
-  remove_hook gdb_update_hook "$this update"
   remove_hook gdb_busy_hook "$this busy"
   remove_hook gdb_no_inferior_hook "$this no_inferior"
   remove_hook gdb_idle_hook "$this idle"
   remove_hook download_progress_hook "$this download_progress"
   remove_hook state_hook [code $this _set_state]
   remove_hook gdb_clear_file_hook [code $this clear_file]
+  set window_list [lremove $window_list $this]
+  if {$pc_window == $this} then {
+    set pc_window ""
+  }
 }
 
 # ------------------------------------------------------------------
@@ -463,19 +471,15 @@
 }
 
 # ------------------------------------------------------------------
-#  PUBLIC METHOD:  update - update widget when PC changes
+#  METHOD:  _update - update widget when PC changes
 # ------------------------------------------------------------------
-body SrcWin::update {} {
-  if {[catch {gdb_loc} loc]} {
-    set_execution_status
-  } else {
-    debug "loc=$loc"
-    # See if name combobox needs filled.
-    if {$need_files} {
-      fillNameCB
-    }
-    location "" $loc
+body SrcWin::_update {loc} {
+  debug "loc=$loc"
+  # See if name combobox needs filled.
+  if {$need_files} {
+    fillNameCB
   }
+  location "" $loc
 }
 
 # ------------------------------------------------------------------
@@ -867,4 +871,122 @@
 
   # run srctextwin clear_file
   $twin clear_file
+}
+
+# ------------------------------------------------------------------
+#  METHOD:  get_file
+#  Return name of displayed file, or empty string if no file.
+# ------------------------------------------------------------------
+body SrcWin::get_file {} {
+  if {$twin == ""} {
+    return ""
+  } else {
+    return [$twin get_file]
+  }
+}
+
+# ------------------------------------------------------------------
+#  METHOD:  is_fixed
+#  Return boolean indicating whether this window is fixed.
+# ------------------------------------------------------------------
+body SrcWin::is_fixed {} {
+  return 0
+}
+
+# ------------------------------------------------------------------
+#  METHOD:  get_top
+#  Return toplevel
+# ------------------------------------------------------------------
+body SrcWin::get_top {} {
+  return $top
+}
+
+# ------------------------------------------------------------------
+#  METHOD:  _set_tag_to_stack
+#  Set tag to `stack' and update the underlying window.
+# ------------------------------------------------------------------
+body SrcWin::_set_tag_to_stack {} {
+  set tag STACK_TAG
+  if {$twin != ""} then {
+    $twin set_tag_to_stack
+  }
+}
+
+# ------------------------------------------------------------------
+#  METHOD:  _choose_window
+#  Choose the right source window.
+# ------------------------------------------------------------------
+body SrcWin::_choose_window {file} {
+  # Find the next available source window.  The rules are:
+  # 1. LRU overall
+  # 2. Skip iconified windows
+  # 3. If a window already shows the file, use it.  Prefer the
+  #    window currently showing the PC
+  # 4. If the window is fixed, skip it
+  if {$pc_window != ""} then {
+    if {[$pc_window get_file] == $file} then {
+      return $pc_window
+    }
+  }
+
+  set choice ""
+  foreach win $window_list {
+    if {[wm state [$win get_top]] != "normal"} then {
+      continue
+    }
+
+    if {[$win get_file] == ""
+	|| [$win get_file] == $file
+	|| ! [$win is_fixed]} then {
+      set choice $win
+      break
+    }
+  }
+
+  # If we didn't find an available window, then pick the current PC
+  # window.
+  if {$choice == ""} then {
+    set choice $pc_window
+  }
+
+  set window_list [lremove $window_list $choice]
+  lappend window_list $choice
+
+  return $choice
+}
+
+# ------------------------------------------------------------------
+#  METHOD:  choose_and_update
+#  Choose the right source window and then cause it to be updated
+# ------------------------------------------------------------------
+body SrcWin::choose_and_update {} {
+  if {$pc_window == ""} then {
+    set pc_window [lindex $window_list 0]
+  }
+
+  if {$pc_window == ""} then {
+    # Nothing.
+  } elseif {[catch {gdb_loc} loc]} {
+    $pc_window set_execution_status
+  } else {
+    set prev $pc_window
+    set file [lindex $loc 2]
+    set pc_window [_choose_window $file]
+    debug "chose window $pc_window"
+    $pc_window _update $loc
+    if {$pc_window != $prev} then {
+      $pc_window reveal
+      $prev _set_tag_to_stack
+    }
+  }
+}
+
+# ------------------------------------------------------------------
+#  METHOD:  choose_and_display
+#  Choose the right source window for a given file
+# ------------------------------------------------------------------
+body SrcWin::choose_and_display {tag linespec} {
+  set file [lindex $linespec 2]
+  set window [_choose_window $file]
+  $window location $tag $linespec
 }
Index: srcwin.ith
===================================================================
RCS file: /cvs/src/src/gdb/gdbtk/library/srcwin.ith,v
retrieving revision 1.3
diff -u -r1.3 srcwin.ith
--- srcwin.ith	2000/11/30 22:49:46	1.3
+++ srcwin.ith	2000/11/30 23:02:54
@@ -48,11 +48,14 @@
     method stack {cmd}
     method test_get {var {private_func 0}}
     method toggle_updates {value}
-    method update {}
     method toolbar {state}
     method inferior {action}
     method clear_file {}
+    method get_file {}
+    method is_fixed {}
 
+    proc choose_and_update {}
+    proc choose_and_display {tag linespec}
     proc point_to_main {}
   }
 
@@ -64,6 +67,10 @@
     method _set_name { val {found 1} }
     method _set_state {varname}
     method _update_title {name}
+    method _update {loc}
+    method get_top {}
+    method _set_tag_to_stack {}
+    proc _choose_window {file}
     variable _statbar
     variable _status
     variable _toolbar
@@ -75,12 +82,18 @@
     variable _mangled_func
     variable Tracing  
     variable saved_msg ""	;# static
-    
+
     # statics used for downloads
     variable last_section ""
     variable last_section_start 0
     variable last_done 0
-    
+
+    # These keep track of the current PC window and the list of all
+    # source windows.
+    common window_list ""
+    common pc_window ""
+    common update_hook_init 0
+
     # fenceposts
     variable Running 0
     variable NoRun 0

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]