]> git.cworth.org Git - sup/commitdiff
Merge branch 'ncurses-fixes' into next
authorWilliam Morgan <wmorgan-sup@masanjin.net>
Thu, 6 Aug 2009 18:30:12 +0000 (14:30 -0400)
committerWilliam Morgan <wmorgan-sup@masanjin.net>
Thu, 6 Aug 2009 18:30:12 +0000 (14:30 -0400)
Conflicts:
bin/sup
lib/sup/buffer.rb

bin/sup
lib/sup/buffer.rb

diff --git a/bin/sup b/bin/sup
index 1febefdd5bc0e06e033f6da7a86d1f5bdf2e710f..0e2260c210fd609feb1584f85a8300e0889b3952 100755 (executable)
--- a/bin/sup
+++ b/bin/sup
@@ -160,6 +160,9 @@ begin
   Redwood::start
   Index.load
 
+  trap("TERM") { |x| raise "so speaking as i think, i die, i die!" }
+  trap("WINCH") { |x| BufferManager.sigwinch_happened! }
+
   if(s = Redwood::SourceManager.source_for DraftManager.source_name)
     DraftManager.source = s
   else
@@ -218,17 +221,28 @@ begin
   end
 
   until Redwood::exceptions.nonempty? || SuicideManager.die?
-    c = 
-       begin
-         Ncurses.nonblocking_getch
-       rescue Exception => e
-         if e.is_a?(Interrupt)
-           raise if BufferManager.ask_yes_or_no("Die ungracefully now?")
-           bm.draw_screen
-           nil
-         end
-       end
-    next unless c
+    c = begin
+      Ncurses.nonblocking_getch
+    rescue Interrupt => e
+      raise if BufferManager.ask_yes_or_no "Die ungracefully now?"
+      BufferManager.draw_screen
+      nil
+    end
+
+    if c.nil?
+      if BufferManager.sigwinch_happened?
+        Redwood::log "redrawing screen on sigwinch"
+        BufferManager.completely_redraw_screen
+      end
+      next
+    end
+
+    if c == 410
+      ## this is ncurses's way of telling us it's detected a refresh.
+      ## since we have our own sigwinch handler, we don't do anything.
+      next
+    end
+
     bm.erase_flash
 
     action =
index 5f52d1dff53ab62f80c008a7a25b6a84505e308c..b3a256fdfb79262bb98295a4c7366ccb4dd531e6 100644 (file)
@@ -28,10 +28,12 @@ module Ncurses
   ## magically, this stuff seems to work now. i could swear it didn't
   ## before. hm.
   def nonblocking_getch
-    if IO.select([$stdin], nil, nil, 1)
-      Ncurses.getch
-    else
-      nil
+    ## INSANTIY
+    ## it is NECESSARY to wrap Ncurses.getch in a select() otherwise all
+    ## background threads will be BLOCKED. (except in very modern versions
+    ## of libncurses-ruby. the current one on ubuntu seems to work well.)
+    if IO.select([$stdin], nil, nil, 0.5)
+      c = Ncurses.getch
     end
   end
 
@@ -196,10 +198,15 @@ EOS
     @flash = nil
     @shelled = @asking = false
     @in_x = ENV["TERM"] =~ /(xterm|rxvt|screen)/
+    @sigwinch_happened = false
+    @sigwinch_mutex = Mutex.new
 
     self.class.i_am_the_instance self
   end
 
+  def sigwinch_happened!; @sigwinch_mutex.synchronize { @sigwinch_happened = true } end
+  def sigwinch_happened?; @sigwinch_mutex.synchronize { @sigwinch_happened } end
+
   def buffers; @name_map.to_a; end
 
   def focus_on buf
@@ -261,6 +268,12 @@ EOS
   def completely_redraw_screen
     return if @shelled
 
+    ## this magic makes Ncurses get the new size of the screen
+    Ncurses.endwin
+    Ncurses.refresh
+    @sigwinch_mutex.synchronize { @sigwinch_happened = false }
+    Redwood::log "new screen size is #{Ncurses.rows} x #{Ncurses.cols}"
+
     status, title = get_status_and_title(@focus_buf) # must be called outside of the ncurses lock
 
     Ncurses.sync do