diff --git a/cbits/hsncurses-shim.c b/cbits/hsncurses-shim.c
--- a/cbits/hsncurses-shim.c
+++ b/cbits/hsncurses-shim.c
@@ -1,13 +1,7 @@
-#define NCURSES_ENABLE_STDBOOL_H 0
-#define _XOPEN_SOURCE_EXTENDED
-#define NCURSES_NOMACROS
+#include <signal.h>
 #include <string.h>
 
-#ifdef HSNCURSES_NARROW_HEADER
-#include <ncurses.h>
-#else
-#include <ncursesw/ncurses.h>
-#endif
+#include "hsncurses-shim.h"
 
 #if NCURSES_VERSION_PATCH < 20081122
 int _nc_has_mouse();
@@ -20,4 +14,26 @@
 #else
 	return _nc_has_mouse();
 #endif
+}
+
+int hsncurses_wget_wch(WINDOW *w, wint_t *out) {
+	/*
+	Haskell's runtime system uses alarm signals to implement thread
+	scheduling. These signals can interrupt system calls such as accept().
+	ncurses doesn't handle interrupted system calls gracefully, so all
+	the alarms can cause wget_wch() to return much earlier than expected.
+	
+	As a workaround, we block alarms for the duration of wget_wch().
+	*/
+	int rc;
+	sigset_t signal_alarm, old_mask;
+	
+	sigemptyset(&signal_alarm);
+	sigaddset(&signal_alarm, SIGALRM);
+	sigaddset(&signal_alarm, SIGVTALRM);
+	
+	pthread_sigmask(SIG_BLOCK, &signal_alarm, &old_mask);
+	rc = wget_wch(w, out);
+	pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
+	return rc;
 }
diff --git a/cbits/hsncurses-shim.h b/cbits/hsncurses-shim.h
--- a/cbits/hsncurses-shim.h
+++ b/cbits/hsncurses-shim.h
@@ -1,1 +1,15 @@
+#include <wchar.h>
+
+#define NCURSES_ENABLE_STDBOOL_H 0
+#define _XOPEN_SOURCE_EXTENDED
+#define NCURSES_NOMACROS
+
+#ifdef HSNCURSES_NARROW_HEADER
+#include <ncurses.h>
+#else
+#include <ncursesw/ncurses.h>
+#endif
+
 int hsncurses_has_mouse();
+
+int hsncurses_wget_wch(WINDOW *, wint_t *);
diff --git a/lib/UI/NCurses.chs b/lib/UI/NCurses.chs
--- a/lib/UI/NCurses.chs
+++ b/lib/UI/NCurses.chs
@@ -148,16 +148,8 @@
 import qualified UI.NCurses.Enums as E
 import           UI.NCurses.Types
 
-#define NCURSES_ENABLE_STDBOOL_H 0
-#define _XOPEN_SOURCE_EXTENDED
-#define NCURSES_NOMACROS
 #include <string.h>
-
-#ifdef HSNCURSES_NARROW_HEADER
-#include <ncurses.h>
-#else
-#include <ncursesw/ncurses.h>
-#endif
+#include "cbits/hsncurses-shim.h"
 
 {# pointer *WINDOW as Window nocode #}
 {# pointer *cchar_t as CCharT newtype #}
@@ -645,7 +637,7 @@
 			Nothing -> -1
 			Just n | n <= 0 -> 0
 			Just n -> fromInteger n
-		rc <- {# call wget_wch #} win ptr
+		rc <- {# call hsncurses_wget_wch #} win ptr
 		if toInteger rc == E.fromEnum E.ERR
 			then return Nothing
 			else fmap Just (parseCode ptr rc)
diff --git a/ncurses.cabal b/ncurses.cabal
--- a/ncurses.cabal
+++ b/ncurses.cabal
@@ -1,5 +1,5 @@
 name: ncurses
-version: 0.2.4
+version: 0.2.5
 license: GPL-3
 license-file: license.txt
 author: John Millikin <jmillikin@gmail.com>
@@ -50,17 +50,18 @@
   cbits/hsncurses-shim.h
 
 source-repository head
-  type: bazaar
-  location: https://john-millikin.com/branches/haskell-ncurses/0.2/
+  type: git
+  location: https://john-millikin.com/code/haskell-ncurses/
 
-source-repository head
-  type: bazaar
-  location: https://john-millikin.com/branches/haskell-ncurses/0.2/
-  tag: haskell-ncurses_0.2.4
+source-repository this
+  type: git
+  location: https://john-millikin.com/code/haskell-ncurses/
+  tag: haskell-ncurses_0.2.5
 
 library
   hs-source-dirs: lib
   ghc-options: -Wall -O2
+  include-dirs: .
 
   build-depends:
       base >= 4.0 && < 5.0
