Package: mozilla-firefox Version: 1.0-2 Severity: wishlist Tags: patch Hi,
The OverTheSpot mode of XIM is the most common input method for Chinese/Japanese users, but it is a pity that gtk2+ library don't support it. There is a patch written by eliu (Vampire at Wicked Empire) <[EMAIL PROTECTED]> could make gtk2+ library to support OverTheSpot mode. Please visit http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=290469 for more details. But mozilla/mozilla-firefox/mozilla-thunderbird still need more patches to make its supporting OverTheSpot mode. The attached file is the patch for mozilla-firefox and mozilla-thunderbird. After some testing, we feel that this patch is stable enough to update to the upstream. Please consider to apply this. Thanks. -- System Information: Debian Release: 3.1 APT prefers testing APT policy: (990, 'testing'), (500, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Kernel: Linux 2.6.8-1-686 Locale: LANG=C, LC_CTYPE=zh_TW.UTF-8 Versions of packages mozilla-firefox depends on: ii debianutils 2.8.4 Miscellaneous utilities specific t ii fontconfig 2.2.3-4.firefly generic font configuration library ii libatk1.0-0 1.8.0-3 The ATK accessibility toolkit ii libc6 2.3.2.ds1-16 GNU C Library: Shared libraries an ii libfontconfig1 2.2.3-4.firefly generic font configuration library ii libfreetype6 2.1.7-2.2 FreeType 2 font engine, shared lib ii libgcc1 1:3.4.1-5 GCC support library ii libglib2.0-0 2.4.7-1 The GLib library of C routines ii libgtk2.0-0 2.4.4-2 The GTK+ graphical user interface ii libidl0 0.8.3-1 library for parsing CORBA IDL file ii libjpeg62 6b-9 The Independent JPEG Group's JPEG ii libkrb53 1.3.3-2 MIT Kerberos runtime libraries ii libpango1.0-0 1.6.0-3 Layout and rendering of internatio ii libpng12-0 1.2.8rel-1 PNG library - runtime ii libstdc++5 1:3.3.4-6sarge1 The GNU Standard C++ Library v3 ii libx11-6 4.3.0.dfsg.1-6 X Window System protocol client li ii libxext6 4.3.0.dfsg.1-6 X Window System miscellaneous exte ii libxft2 2.1.2-6.firefly FreeType-based font drawing librar ii libxp6 4.3.0.dfsg.1-4 X Window System printing extension ii libxrender1 0.8.3-7 X Rendering Extension client libra ii libxt6 4.3.0.dfsg.1-4 X Toolkit Intrinsics ii psmisc 21.5-1 Utilities that use the proc filesy ii xlibs 4.3.0.dfsg.1-4 X Window System client libraries m ii zlib1g 1:1.2.1.1-5 compression library - runtime -- no debconf information
diff -uNr mozilla.orig/widget/src/gtk2/nsCommonWidget.cpp mozilla/widget/src/gtk2/nsCommonWidget.cpp --- mozilla.orig/widget/src/gtk2/nsCommonWidget.cpp 2005-01-08 18:40:36.000000000 +0800 +++ mozilla/widget/src/gtk2/nsCommonWidget.cpp 2005-01-08 18:42:01.000000000 +0800 @@ -451,3 +451,34 @@ return PR_FALSE; } + +#include "nsWindow.h" + +extern nsWindow *gFocusWindow; + +PRBool nsCommonWidget::OnInput(nsInputEvent &aEvent) +{ + + PRBool ret = PR_FALSE; + PRBool releaseWidget = PR_FALSE; + nsCommonWidget *widget = NULL; + + +// printf("gFocusWindow win %x\n", gFocusWindow); + // rewrite the key event to the window with 'de focus + if (gFocusWindow) { + widget = gFocusWindow; + NS_ADDREF(widget); + aEvent.widget = gFocusWindow; + releaseWidget = PR_TRUE; + } + if (mEventCallback) { + nsEventStatus aStatus; + ret = DispatchEvent(&aEvent, aStatus); + } + + if (releaseWidget) + NS_RELEASE(widget); + + return ret; +} diff -uNr mozilla.orig/widget/src/gtk2/nsCommonWidget.h mozilla/widget/src/gtk2/nsCommonWidget.h --- mozilla.orig/widget/src/gtk2/nsCommonWidget.h 2005-01-08 18:40:36.000000000 +0800 +++ mozilla/widget/src/gtk2/nsCommonWidget.h 2005-01-08 18:43:26.000000000 +0800 @@ -112,6 +112,9 @@ NS_IMETHOD Enable (PRBool aState); NS_IMETHOD IsEnabled (PRBool *aState); + PRBool OnComposition(nsCompositionEvent &aEvent) { return OnInput(aEvent); }; + PRBool OnInput(nsInputEvent &aEvent); + // called when we are destroyed void OnDestroy(void); diff -uNr mozilla.orig/widget/src/gtk2/nsWindow.cpp mozilla/widget/src/gtk2/nsWindow.cpp --- mozilla.orig/widget/src/gtk2/nsWindow.cpp 2005-01-08 18:40:36.000000000 +0800 +++ mozilla/widget/src/gtk2/nsWindow.cpp 2005-01-08 18:51:37.000000000 +0800 @@ -73,6 +73,11 @@ static const char sAccessibilityKey [] = "config.use_system_prefs.accessibility"; #endif +struct nsXICLookupEntry : public PLDHashEntryHdr { + nsWindow* mShellWindow; + GtkIMContext* mXIC; +}; + /* For SetIcon */ #include "nsAppDirectoryServiceDefs.h" #include "nsXPIDLString.h" @@ -189,7 +194,7 @@ static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID); // the current focus window -static nsWindow *gFocusWindow = NULL; +nsWindow *gFocusWindow = NULL; static PRBool gGlobalsInitialized = PR_FALSE; static PRBool gRaiseWindows = PR_TRUE; static nsWindow *gPluginFocusWindow = NULL; @@ -276,6 +281,8 @@ nsWindow::~nsWindow() { + KillICSpotTimer(); + LOG(("nsWindow::~nsWindow() [%p]\n", (void *)this)); if (mLastDragMotionWindow == this) { mLastDragMotionWindow = NULL; @@ -1155,6 +1162,8 @@ void nsWindow::LoseFocus(void) { +// printf("LoseFocus ... %x\n", this); + // make sure that we reset our repeat counter so the next keypress // for this widget will get the down event mInKeyRepeat = PR_FALSE; @@ -3898,6 +3907,109 @@ #ifdef USE_XIM +nsresult nsWindow::KillICSpotTimer () +{ + if(mICSpotTimer) + { +// printf("KillICSpotTimer %x\n", this); + mICSpotTimer->Cancel(); + mICSpotTimer = nsnull; + } + return NS_OK; +} + +nsresult nsWindow::PrimeICSpotTimer () +{ + KillICSpotTimer(); + nsresult err; + mICSpotTimer = do_CreateInstance("@mozilla.org/timer;1", &err); + if (NS_FAILED(err)) + return err; +// printf("PrimeICSpotTimer %x\n", this); + mICSpotTimer->InitWithFuncCallback(ICSpotCallback, this, 1000, + nsITimer::TYPE_ONE_SHOT); + return NS_OK; +} + +void nsWindow::ICSpotCallback(nsITimer * aTimer, void * aClosure) +{ + nsWindow *window= NS_REINTERPRET_CAST(nsWindow*, aClosure); + if( ! window) return; + nsresult res = NS_ERROR_FAILURE; + + GtkIMContext *im = window->IMEGetContext(); + + if (im) { + res = window->UpdateICSpot(); + } + if(NS_SUCCEEDED(res)) + { +// printf("ICSpotCallback\n"); + window->PrimeICSpotTimer(); + } +} + +nsresult nsWindow::UpdateICSpot() +{ + GtkIMContext *im; +#if 1 + if (!gFocusWindow || !(im=gFocusWindow->IMEGetContext())) + return NS_ERROR_FAILURE; +#endif + + // set spot location + nsCompositionEvent compEvent(NS_COMPOSITION_QUERY, this); + static gint oldx =0; + static gint oldy =0; + + compEvent.theReply.mCursorPosition.x=-1; + compEvent.theReply.mCursorPosition.y=-1; + this->OnComposition(compEvent); + // set SpotLocation + if((compEvent.theReply.mCursorPosition.x < 0) && + (compEvent.theReply.mCursorPosition.y < 0)) + return NS_ERROR_FAILURE; + +// im=gFocusWindow->IMEGetContext(); + + if((compEvent.theReply.mCursorPosition.x != oldx)|| + (compEvent.theReply.mCursorPosition.y != oldy)) + { + nsRect a,b,c; + + a.x=0; b.x=0; + gFocusWindow->WidgetToScreen(a, b); + + GtkWidget *owningWidget = + get_gtk_widget_for_gdk_window(gFocusWindow->mDrawingarea->inner_window); + nsWindow *owningWindow = get_window_for_gtk_widget(owningWidget); + owningWindow->WidgetToScreen(a, c); + + int dx = b.x - c.x, dy = b.y - c.y; + + nsPoint spot; + spot.x = dx + compEvent.theReply.mCursorPosition.x; + spot.y = dy + compEvent.theReply.mCursorPosition.y +#if 0 + + compEvent.theReply.mCursorPosition.height +#endif + ; + + GdkRectangle rect; + rect.x = spot.x; rect.y = spot.y; + rect.width = compEvent.theReply.mCursorPosition.width; + rect.height = 0; + +// printf("cursor %d %d %x\n", spot.x, spot.y, im); + gtk_im_context_set_cursor_location(im, &rect); + + oldx = compEvent.theReply.mCursorPosition.x; + oldy = compEvent.theReply.mCursorPosition.y; + } + return NS_OK; +} + + void nsWindow::IMEDestroyContext(void) { @@ -3925,13 +4037,20 @@ if (!im) return; +// printf("IMESetFocus im:%x win:%x\n", im, this); gtk_im_context_focus_in(im); gIMEFocusWindow = this; +#if 1 + UpdateICSpot(); + PrimeICSpotTimer(); +#endif } void nsWindow::IMELoseFocus(void) { + KillICSpotTimer(); + LOGIM(("IMELoseFocus %p\n", (void *)this)); GtkIMContext *im = IMEGetContext(); if (!im) @@ -4175,6 +4294,13 @@ } g_free(uniStr); + +#ifdef USE_XIM && 1 + if (window->IMEGetContext()) { + window->UpdateICSpot(); + window->PrimeICSpotTimer(); + } +#endif // USE_XIM } #define START_OFFSET(I) \ @@ -4302,6 +4428,9 @@ GtkIMContext * IM_get_input_context(MozDrawingarea *aArea) { + if (!aArea) + return NULL; + GtkWidget *owningWidget = get_gtk_widget_for_gdk_window(aArea->inner_window); diff -uNr mozilla.orig/widget/src/gtk2/nsWindow.h mozilla/widget/src/gtk2/nsWindow.h --- mozilla.orig/widget/src/gtk2/nsWindow.h 2005-01-08 18:40:36.000000000 +0800 +++ mozilla/widget/src/gtk2/nsWindow.h 2005-01-08 18:49:40.000000000 +0800 @@ -267,6 +267,11 @@ GtkIMContext *mIMContext; PRBool mComposingText; + nsCOMPtr<nsITimer> mICSpotTimer; + static void ICSpotCallback(nsITimer* aTimer, void* aClosure); + nsresult KillICSpotTimer(); + nsresult PrimeICSpotTimer(); + nsresult UpdateICSpot(); #endif private: