]> git.cworth.org Git - sup/commitdiff
Merge branch 'ncurses-fixes'
authorWilliam Morgan <wmorgan-sup@masanjin.net>
Tue, 25 Aug 2009 13:39:18 +0000 (09:39 -0400)
committerWilliam Morgan <wmorgan-sup@masanjin.net>
Tue, 25 Aug 2009 13:48:20 +0000 (09:48 -0400)
Conflicts:
lib/sup/buffer.rb

bin/sup
lib/sup/buffer.rb
lib/sup/suicide.rb

diff --git a/bin/sup b/bin/sup
index 7a51800a461c2c82a6a6f35e2b075451f05991bb..8a377f78149f5a4b17a56e06036fcae96e2b3fb6 100755 (executable)
--- a/bin/sup
+++ b/bin/sup
@@ -161,6 +161,9 @@ begin
   Redwood::start
   Index.load
 
+  trap("TERM") { |x| SuicideManager.please_die! }
+  trap("WINCH") { |x| BufferManager.sigwinch_happened! }
+
   if(s = Redwood::SourceManager.source_for DraftManager.source_name)
     DraftManager.source = s
   else
@@ -225,29 +228,39 @@ 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?
+        debug "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 =
-      begin
-        if bm.handle_input c
-          :nothing
-        else
-          bm.resolve_input_with_keymap c, global_keymap
-        end
-      rescue InputSequenceAborted
+    action = begin
+      if bm.handle_input c
         :nothing
+      else
+        bm.resolve_input_with_keymap c, global_keymap
       end
+    rescue InputSequenceAborted
+      :nothing
+    end
     case action
     when :quit_now
       break if bm.kill_all_buffers_safely
index f053f676e53262f2680c52b46fb21134d437d69e..4b53fed697b037656cdec013a64da1bb5e78f59c 100644 (file)
@@ -25,13 +25,13 @@ module Ncurses
   def mutex; @mutex ||= Mutex.new; end
   def sync &b; mutex.synchronize(&b); end
 
-  ## 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
 
@@ -70,7 +70,7 @@ class Buffer
   def content_height; @height - 1; end
   def content_width; @width; end
 
-  def resize rows, cols 
+  def resize rows, cols
     return if cols == @width && rows == @height
     @width = cols
     @height = rows
@@ -196,8 +196,13 @@ EOS
     @flash = nil
     @shelled = @asking = false
     @in_x = ENV["TERM"] =~ /(xterm|rxvt|screen)/
+    @sigwinch_happened = false
+    @sigwinch_mutex = Mutex.new
   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
@@ -259,6 +264,14 @@ EOS
   def completely_redraw_screen
     return if @shelled
 
+    ## this magic makes Ncurses get the new size of the screen
+    Ncurses.endwin
+    Ncurses.stdscr.keypad 1
+    Ncurses.curs_set 0
+    Ncurses.refresh
+    @sigwinch_mutex.synchronize { @sigwinch_happened = false }
+    debug "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
index bef63258ed70b57fe2607492671d8a510b3f6bbc..09fc7b8b22379dc02d364a39b48b2e247d7e2bd3 100644 (file)
@@ -13,6 +13,7 @@ class SuicideManager
   end
 
   bool_reader :die
+  def please_die!; @die = true end
 
   def start
     @thread = Redwood::reporting_thread("suicide watch") do