diff -up fltk-1.3.2/FL/Fl.H.im fltk-1.3.2/FL/Fl.H
--- fltk-1.3.2/FL/Fl.H.im	2014-09-10 14:40:05.193265424 +0200
+++ fltk-1.3.2/FL/Fl.H	2014-09-10 14:40:05.196265471 +0200
@@ -699,6 +699,17 @@ public:
   static int event_inside(const Fl_Widget*);
   static int test_shortcut(Fl_Shortcut);
 
+  /**
+    Enables the system input methods facilities. This is the default.
+    \see disable_im()
+  */
+  static void enable_im();
+  /**
+    Disables the system input methods facilities.
+    \see enable_im()
+  */
+  static void disable_im();
+
   // event destinations:
   static int handle(int, Fl_Window*);
   static int handle_(int, Fl_Window*);
diff -up fltk-1.3.2/FL/win32.H.im fltk-1.3.2/FL/win32.H
--- fltk-1.3.2/FL/win32.H.im	2014-09-10 14:40:05.186265315 +0200
+++ fltk-1.3.2/FL/win32.H	2014-09-10 14:40:05.196265471 +0200
@@ -102,6 +102,8 @@ extern FL_EXPORT void fl_save_dc( HWND w
 
 inline Window fl_xid(const Fl_Window* w) { Fl_X *temp = Fl_X::i(w); return temp ? temp->xid : 0; }
 
+extern FL_EXPORT void fl_open_display();
+
 #else
 FL_EXPORT Window fl_xid_(const Fl_Window* w);
 #define fl_xid(w) fl_xid_(w)
diff -up fltk-1.3.2/src/Fl_cocoa.mm.im fltk-1.3.2/src/Fl_cocoa.mm
--- fltk-1.3.2/src/Fl_cocoa.mm.im	2014-09-10 14:40:05.193265424 +0200
+++ fltk-1.3.2/src/Fl_cocoa.mm	2014-09-10 14:43:41.103642243 +0200
@@ -88,6 +88,7 @@ static void createAppleMenu(void);
 static Fl_Region MacRegionMinusRect(Fl_Region r, int x,int y,int w,int h);
 static void cocoaMouseHandler(NSEvent *theEvent);
 static int calc_mac_os_version();
+static void im_update(void);
 
 static Fl_Quartz_Graphics_Driver fl_quartz_driver;
 static Fl_Display_Device fl_quartz_display(&fl_quartz_driver);
@@ -108,6 +109,30 @@ int fl_mac_os_version = calc_mac_os_vers
 static int got_events = 0;
 static Fl_Window* resize_from_system;
 static int main_screen_height; // height of menubar-containing screen used to convert between Cocoa and FLTK global screen coordinates
+static int im_enabled = -1;
+
+// Carbon functions and definitions
+
+typedef void *TSMDocumentID;
+
+extern "C" enum {
+ kTSMDocumentEnabledInputSourcesPropertyTag = 'enis' //  from Carbon/TextServices.h
+};
+
+// Undocumented voodoo. Taken from Mozilla.
+static const int smEnableRomanKybdsOnly = -23;
+
+typedef TSMDocumentID (*TSMGetActiveDocument_type)(void);
+static TSMGetActiveDocument_type TSMGetActiveDocument;
+typedef OSStatus (*TSMSetDocumentProperty_type)(TSMDocumentID, OSType, UInt32, void*);
+static TSMSetDocumentProperty_type TSMSetDocumentProperty;
+typedef OSStatus (*TSMRemoveDocumentProperty_type)(TSMDocumentID, OSType);
+static TSMRemoveDocumentProperty_type TSMRemoveDocumentProperty;
+typedef CFArrayRef (*TISCreateASCIICapableInputSourceList_type)(void);
+static TISCreateASCIICapableInputSourceList_type TISCreateASCIICapableInputSourceList;
+
+typedef void (*KeyScript_type)(short);
+static KeyScript_type KeyScript;
 
 #if CONSOLIDATE_MOTION
 static Fl_Window* send_motion;
@@ -978,6 +1003,7 @@ void fl_open_callback(void (*cb)(const c
 #endif
 {
   BOOL seen_open_file;
+  TSMDocumentID currentDoc;
 }
 - (void)windowDidMove:(NSNotification *)notif;
 - (void)windowDidResize:(NSNotification *)notif;
@@ -991,6 +1017,7 @@ void fl_open_callback(void (*cb)(const c
 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender;
 - (void)applicationDidBecomeActive:(NSNotification *)notify;
 - (void)applicationDidChangeScreenParameters:(NSNotification *)aNotification;
+- (void)applicationDidUpdate:(NSNotification *)aNotification;
 - (void)applicationWillResignActive:(NSNotification *)notify;
 - (void)applicationWillHide:(NSNotification *)notify;
 - (void)applicationWillUnhide:(NSNotification *)notify;
@@ -1175,6 +1202,23 @@ void fl_open_callback(void (*cb)(const c
     }
   Fl::handle(FL_SCREEN_CONFIGURATION_CHANGED, NULL);
 }
+- (void)applicationDidUpdate:(NSNotification *)aNotification
+{
+  if ((fl_mac_os_version >= 100500) && (im_enabled != -1) &&
+      (TSMGetActiveDocument != NULL)) {
+    TSMDocumentID newDoc;
+    // It is extremely unclear when Cocoa decides to create/update
+    // the input context, but debugging reveals that it is done
+    // by NSApplication:updateWindows. So check if the input context
+    // has shifted after each such run so that we can update our
+    // input methods status.
+    newDoc = TSMGetActiveDocument();
+    if (newDoc != currentDoc) {
+        im_update();
+        currentDoc = newDoc;
+    }
+  }
+}
 - (void)applicationWillResignActive:(NSNotification *)notify
 {
   fl_lock_function();
@@ -1322,6 +1365,13 @@ void fl_open_display() {
   static char beenHereDoneThat = 0;
   if ( !beenHereDoneThat ) {
     beenHereDoneThat = 1;
+
+    TSMGetActiveDocument = (TSMGetActiveDocument_type)Fl_X::get_carbon_function("TSMGetActiveDocument");
+    TSMSetDocumentProperty = (TSMSetDocumentProperty_type)Fl_X::get_carbon_function("TSMSetDocumentProperty");
+    TSMRemoveDocumentProperty = (TSMRemoveDocumentProperty_type)Fl_X::get_carbon_function("TSMRemoveDocumentProperty");
+    TISCreateASCIICapableInputSourceList = (TISCreateASCIICapableInputSourceList_type)Fl_X::get_carbon_function("TISCreateASCIICapableInputSourceList");
+
+    KeyScript = (KeyScript_type)Fl_X::get_carbon_function("KeyScript");
     
     BOOL need_new_nsapp = (NSApp == nil);
     if (need_new_nsapp) [NSApplication sharedApplication];
@@ -1390,6 +1440,66 @@ void fl_open_display() {
 void fl_close_display() {
 }
 
+// Force a "Roman" or "ASCII" keyboard, which both the Mozilla and
+// Safari people seem to think implies turning off advanced IME stuff
+// (see nsTSMManager::SyncKeyScript in Mozilla and enableSecureTextInput
+// in Safari/Webcore). Should be good enough for us then...
+
+static void im_update(void) {
+  if (fl_mac_os_version >= 100500) {
+    TSMDocumentID doc;
+
+    if ((TSMGetActiveDocument == NULL) ||
+        (TSMSetDocumentProperty == NULL) ||
+        (TSMRemoveDocumentProperty == NULL) ||
+        (TISCreateASCIICapableInputSourceList == NULL))
+      return;
+
+    doc = TSMGetActiveDocument();
+
+    if (im_enabled)
+      TSMRemoveDocumentProperty(doc, kTSMDocumentEnabledInputSourcesPropertyTag);
+    else {
+      CFArrayRef inputSources;
+
+      inputSources = TISCreateASCIICapableInputSourceList();
+      TSMSetDocumentProperty(doc, kTSMDocumentEnabledInputSourcesPropertyTag,
+                             sizeof(CFArrayRef), &inputSources);
+      CFRelease(inputSources);
+    }
+  } else {
+    if (KeyScript == NULL)
+      return;
+
+    if (im_enabled)
+      KeyScript(smKeyEnableKybds);
+    else
+      KeyScript(smEnableRomanKybdsOnly);
+  }
+}
+
+void Fl::enable_im() {
+  fl_open_display();
+
+  im_enabled = 1;
+
+  if (fl_mac_os_version >= 100500)
+    [NSApp updateWindows];
+  else
+    im_update();
+}
+
+void Fl::disable_im() {
+  fl_open_display();
+
+  im_enabled = 0;
+
+  if (fl_mac_os_version >= 100500)
+    [NSApp updateWindows];
+  else
+    im_update();
+}
+
 
 // Gets the border sizes and the titlebar size
 static void get_window_frame_sizes(int &bx, int &by, int &bt) {
diff -up fltk-1.3.2/src/Fl.cxx.im fltk-1.3.2/src/Fl.cxx
--- fltk-1.3.2/src/Fl.cxx.im	2014-09-10 14:40:05.194265440 +0200
+++ fltk-1.3.2/src/Fl.cxx	2014-09-10 14:40:05.197265486 +0200
@@ -593,45 +593,6 @@ int Fl::run() {
   return 0;
 }
 
-#ifdef WIN32
-
-// Function to initialize COM/OLE for usage. This must be done only once.
-// We define a flag to register whether we called it:
-static char oleInitialized = 0;
-
-// This calls the Windows function OleInitialize() exactly once.
-void fl_OleInitialize() {
-  if (!oleInitialized) {
-    OleInitialize(0L);
-    oleInitialized = 1;
-  }
-}
-
-// This calls the Windows function OleUninitialize() only, if
-// OleInitialize has been called before.
-void fl_OleUninitialize() {
-  if (oleInitialized) {
-    OleUninitialize();
-    oleInitialized = 0;
-  }
-}
-
-class Fl_Win32_At_Exit {
-public:
-  Fl_Win32_At_Exit() { }
-  ~Fl_Win32_At_Exit() {
-    fl_free_fonts();        // do some WIN32 cleanup
-    fl_cleanup_pens();
-    fl_OleUninitialize();
-    fl_brush_action(1);
-    fl_cleanup_dc_list();
-  }
-};
-static Fl_Win32_At_Exit win32_at_exit;
-#endif
-
-
-
 /**
   Waits until "something happens" and then returns.  Call this
   repeatedly to "run" your program.  You can also check what happened
diff -up fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx.im fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx
--- fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx.im	2012-06-26 09:03:46.000000000 +0200
+++ fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx	2014-09-10 14:40:05.197265486 +0200
@@ -34,6 +34,7 @@ LPCWSTR utf8towchar(const char *in); //M
 char *wchartoutf8(LPCWSTR in);  //MG
 
 #include <FL/Fl_Native_File_Chooser.H>
+#include <FL/x.H>
 
 #define LCURLY_CHR	'{'
 #define RCURLY_CHR	'}'
@@ -41,8 +42,6 @@ char *wchartoutf8(LPCWSTR in);  //MG
 #define RBRACKET_CHR	']'
 #define MAXFILTERS	80
 
-void fl_OleInitialize();	// in Fl.cxx (Windows only)
-
 // STATIC: PRINT WINDOWS 'DOUBLE NULL' STRING (DEBUG)
 #ifdef DEBUG
 static void dnullprint(char *wp) {
@@ -471,7 +470,7 @@ int CALLBACK Fl_Native_File_Chooser::Dir
 // SHOW DIRECTORY BROWSER
 int Fl_Native_File_Chooser::showdir() {
   // initialize OLE only once
-  fl_OleInitialize();		// init needed by BIF_USENEWUI
+  fl_open_display();		// init needed by BIF_USENEWUI
   ClearBINF();
   clear_pathnames();
   // PARENT WINDOW
diff -up fltk-1.3.2/src/Fl_win32.cxx.im fltk-1.3.2/src/Fl_win32.cxx
--- fltk-1.3.2/src/Fl_win32.cxx.im	2014-09-10 14:40:05.194265440 +0200
+++ fltk-1.3.2/src/Fl_win32.cxx	2014-09-10 14:40:05.197265486 +0200
@@ -60,8 +60,6 @@
 #include <ole2.h>
 #include <shellapi.h>
 
-#include "aimm.h"
-
 //
 // USE_ASYNC_SELECT - define it if you have WSAAsyncSelect()...
 // USE_ASYNC_SELECT is OBSOLETED in 1.3 for the following reasons:
@@ -121,27 +119,24 @@ static HMODULE get_wsock_mod() {
  * size and link dependencies.
  */
 static HMODULE s_imm_module = 0;
+typedef BOOL (WINAPI* flTypeImmAssociateContextEx)(HWND, HIMC, DWORD);
+static flTypeImmAssociateContextEx flImmAssociateContextEx = 0;
 typedef HIMC (WINAPI* flTypeImmGetContext)(HWND);
 static flTypeImmGetContext flImmGetContext = 0;
 typedef BOOL (WINAPI* flTypeImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM);
 static flTypeImmSetCompositionWindow flImmSetCompositionWindow = 0;
 typedef BOOL (WINAPI* flTypeImmReleaseContext)(HWND, HIMC);
 static flTypeImmReleaseContext flImmReleaseContext = 0;
-typedef BOOL (WINAPI* flTypeImmIsIME)(HKL);
-static flTypeImmIsIME flImmIsIME = 0;
 
-static HMODULE get_imm_module() {
-  if (!s_imm_module) {
-    s_imm_module = LoadLibrary("IMM32.DLL");
-    if (!s_imm_module)
-      Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n"
-        "Please check your input method manager library accessibility.");
-    flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext");
-    flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow");
-    flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext");
-    flImmIsIME = (flTypeImmIsIME)GetProcAddress(s_imm_module, "ImmIsIME");
-  }
-  return s_imm_module;
+static void get_imm_module() {
+  s_imm_module = LoadLibrary("IMM32.DLL");
+  if (!s_imm_module)
+    Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n"
+      "Please check your input method manager library accessibility.");
+  flImmAssociateContextEx = (flTypeImmAssociateContextEx)GetProcAddress(s_imm_module, "ImmAssociateContextEx");
+  flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext");
+  flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow");
+  flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext");
 }
 
 // USE_TRACK_MOUSE - define NO_TRACK_MOUSE if you don't have
@@ -259,7 +254,9 @@ void fl_set_spot(int font, int size, int
   Fl_Window* tw = win;
   while (tw->parent()) tw = tw->window(); // find top level window
 
-  get_imm_module();
+  if (!tw->shown())
+    return;
+
   HIMC himc = flImmGetContext(fl_xid(tw));
 
   if (himc) {
@@ -338,7 +335,6 @@ void* Fl::thread_message() {
 
 extern int fl_send_system_handlers(void *e);
 
-IActiveIMMApp *fl_aimm = NULL;
 MSG fl_msg;
 
 // This is never called with time_to_wait < 0.0.
@@ -441,6 +437,58 @@ int fl_ready() {
   return get_wsock_mod() ? s_wsock_select(0,&fdt[0],&fdt[1],&fdt[2],&t) : 0;
 }
 
+void fl_open_display() {
+  static char beenHereDoneThat = 0;
+
+  if (beenHereDoneThat)
+    return;
+
+  beenHereDoneThat = 1;
+
+  OleInitialize(0L);
+
+  get_imm_module();
+}
+
+class Fl_Win32_At_Exit {
+public:
+  Fl_Win32_At_Exit() { }
+  ~Fl_Win32_At_Exit() {
+    fl_free_fonts();        // do some WIN32 cleanup
+    fl_cleanup_pens();
+    OleUninitialize();
+    fl_brush_action(1);
+    fl_cleanup_dc_list();
+  }
+};
+static Fl_Win32_At_Exit win32_at_exit;
+
+static char im_enabled = 1;
+
+void Fl::enable_im() {
+  fl_open_display();
+
+  Fl_X* i = Fl_X::first;
+  while (i) {
+    flImmAssociateContextEx(i->xid, 0, IACE_DEFAULT);
+    i = i->next;
+  }
+
+  im_enabled = 1;
+}
+
+void Fl::disable_im() {
+  fl_open_display();
+
+  Fl_X* i = Fl_X::first;
+  while (i) {
+    flImmAssociateContextEx(i->xid, 0, 0);
+    i = i->next;
+  }
+
+  im_enabled = 0;
+}
+
 ////////////////////////////////////////////////////////////////
 
 int Fl::x()
@@ -683,7 +731,6 @@ void fl_clipboard_notify_untarget(HWND w
 }
 
 ////////////////////////////////////////////////////////////////
-char fl_is_ime = 0;
 void fl_get_codepage()
 {
   HKL hkl = GetKeyboardLayout(0);
@@ -691,14 +738,8 @@ void fl_get_codepage()
 
   GetLocaleInfo (LOWORD(hkl), LOCALE_IDEFAULTANSICODEPAGE, ld, 6);
   DWORD ccp = atol(ld);
-  fl_is_ime = 0;
 
   fl_codepage = ccp;
-  if (fl_aimm) {
-    fl_aimm->GetCodePageA(GetKeyboardLayout(0), &fl_codepage);
-  } else if (get_imm_module() && flImmIsIME(hkl)) {
-    fl_is_ime = 1;
-  }
 }
 
 HWND fl_capture;
@@ -1564,6 +1605,8 @@ int fl_disable_transient_for; // secret
 Fl_X* Fl_X::make(Fl_Window* w) {
   Fl_Group::current(0); // get rid of very common user bug: forgot end()
 
+  fl_open_display();
+
   // if the window is a subwindow and our parent is not mapped yet, we
   // mark this window visible, so that mapping the parent at a later
   // point in time will call this function again to finally map the subwindow.
@@ -1767,16 +1810,10 @@ Fl_X* Fl_X::make(Fl_Window* w) {
 	     (Fl::grab() || (styleEx & WS_EX_TOOLWINDOW)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
 
   // Register all windows for potential drag'n'drop operations
-  fl_OleInitialize();
   RegisterDragDrop(x->xid, flIDropTarget);
 
-  if (!fl_aimm) {
-    CoCreateInstance(CLSID_CActiveIMM, NULL, CLSCTX_INPROC_SERVER,
-		     IID_IActiveIMMApp, (void**) &fl_aimm);
-    if (fl_aimm) {
-      fl_aimm->Activate(TRUE);
-    }
-  }
+  if (!im_enabled)
+    flImmAssociateContextEx(x->xid, 0, 0);
 
   return x;
 }
diff -up fltk-1.3.2/src/Fl_x.cxx.im fltk-1.3.2/src/Fl_x.cxx
--- fltk-1.3.2/src/Fl_x.cxx.im	2014-09-10 14:40:05.194265440 +0200
+++ fltk-1.3.2/src/Fl_x.cxx	2014-09-10 14:40:05.198265502 +0200
@@ -313,6 +313,7 @@ XVisualInfo *fl_visual;
 Colormap fl_colormap;
 XIM fl_xim_im = 0;
 XIC fl_xim_ic = 0;
+Window fl_xim_win = 0;
 char fl_is_over_the_spot = 0;
 static XRectangle status_area;
 
@@ -603,6 +604,55 @@ void fl_init_xim() {
   if(xim_styles) XFree(xim_styles);
 }
 
+void fl_xim_deactivate(void);
+
+void fl_xim_activate(Window xid) {
+  if (!fl_xim_im)
+    return;
+
+  // If the focused window has changed, then use the brute force method
+  // of completely recreating the input context.
+  if (fl_xim_win != xid) {
+    fl_xim_deactivate();
+
+    fl_new_ic();
+    fl_xim_win = xid;
+
+    XSetICValues(fl_xim_ic,
+                 XNFocusWindow, fl_xim_win,
+                 XNClientWindow, fl_xim_win,
+                 NULL);
+  }
+
+  fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
+}
+
+void fl_xim_deactivate(void) {
+  if (!fl_xim_ic)
+    return;
+
+  XDestroyIC(fl_xim_ic);
+  fl_xim_ic = NULL;
+
+  fl_xim_win = 0;
+}
+
+void Fl::enable_im() {
+  Fl_Window *win;
+
+  win = Fl::first_window();
+  if (win && win->shown()) {
+    fl_xim_activate(fl_xid(win));
+    XSetICFocus(fl_xim_ic);
+  } else {
+    fl_new_ic();
+  }
+}
+
+void Fl::disable_im() {
+  fl_xim_deactivate();
+}
+
 void fl_open_display() {
   if (fl_display) return;
 
@@ -1053,10 +1103,9 @@ int fl_handle(const XEvent& thisevent)
   XEvent xevent = thisevent;
   fl_xevent = &thisevent;
   Window xid = xevent.xany.window;
-  static Window xim_win = 0;
 
   if (fl_xim_ic && xevent.type == DestroyNotify &&
-        xid != xim_win && !fl_find(xid))
+        xid != fl_xim_win && !fl_find(xid))
   {
     XIM xim_im;
     xim_im = XOpenIM(fl_display, NULL, NULL, NULL);
@@ -1072,46 +1121,9 @@ int fl_handle(const XEvent& thisevent)
   }
 
   if (fl_xim_ic && (xevent.type == FocusIn))
-  {
-#define POOR_XIM
-#ifdef POOR_XIM
-        if (xim_win != xid)
-        {
-                xim_win  = xid;
-                XDestroyIC(fl_xim_ic);
-                fl_xim_ic = NULL;
-                fl_new_ic();
-                XSetICValues(fl_xim_ic,
-                                XNFocusWindow, xevent.xclient.window,
-                                XNClientWindow, xid,
-                                NULL);
-        }
-        fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
-#else
-    if (Fl::first_window() && Fl::first_window()->modal()) {
-      Window x  = fl_xid(Fl::first_window());
-      if (x != xim_win) {
-        xim_win  = x;
-        XSetICValues(fl_xim_ic,
-                        XNFocusWindow, xim_win,
-                        XNClientWindow, xim_win,
-                        NULL);
-        fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
-      }
-    } else if (xim_win != xid && xid) {
-      xim_win = xid;
-      XSetICValues(fl_xim_ic,
-                        XNFocusWindow, xevent.xclient.window,
-                        XNClientWindow, xid,
-                        //XNFocusWindow, xim_win,
-                        //XNClientWindow, xim_win,
-                        NULL);
-      fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
-    }
-#endif
-  }
+    fl_xim_activate(xid);
 
-  if ( XFilterEvent((XEvent *)&xevent, 0) )
+  if (fl_xim_ic && XFilterEvent((XEvent *)&xevent, 0))
       return(1);
   
 #if USE_XRANDR  
