add query composition event which get current curosor position. add timer base IME x y location query for gtk. r=erik. fix bug 17916 20550

This commit is contained in:
ftang%netscape.com 1999-12-07 01:29:00 +00:00
parent 0f7a29f233
commit 5d9824b4bd
21 changed files with 175 additions and 33 deletions

View File

@ -317,7 +317,8 @@ NS_METHOD nsDOMEvent::GetEventReply(nsTextEventReply** aReply)
NS_METHOD nsDOMEvent::GetCompositionReply(nsTextEventReply** aReply)
{
if (mEvent->message==NS_COMPOSITION_START) {
if((mEvent->message==NS_COMPOSITION_START) ||
(mEvent->message==NS_COMPOSITION_QUERY)) {
*aReply = &(((nsCompositionEvent*)mEvent)->theReply);
return NS_OK;
}

View File

@ -821,6 +821,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
case NS_COMPOSITION_START:
case NS_COMPOSITION_END:
case NS_COMPOSITION_QUERY:
#if DEBUG_TAGUE
printf("DOM: got composition event\n");
#endif
@ -842,6 +843,9 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
if (aEvent->message==NS_COMPOSITION_END) {
ret = mCompositionListener->HandleEndComposition(*aDOMEvent);
}
if (aEvent->message==NS_COMPOSITION_QUERY) {
ret = mCompositionListener->HandleQueryComposition(*aDOMEvent);
}
}
NS_RELEASE(mCompositionListener);
}
@ -861,6 +865,12 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
correctSubType = PR_TRUE;
}
break;
case NS_COMPOSITION_QUERY:
subType = NS_EVENT_BITS_COMPOSITION_QUERY;
if (ls->mSubType & NS_EVENT_BITS_COMPOSITION_QUERY) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}

View File

@ -160,6 +160,7 @@ protected:
#define NS_EVENT_BITS_COMPOSITION_NONE 0x00
#define NS_EVENT_BITS_COMPOSITION_START 0x01
#define NS_EVENT_BITS_COMPOSITION_END 0x02
#define NS_EVENT_BITS_COMPOSITION_QUERY 0x04
//nsIDOMFocusListener
#define NS_EVENT_BITS_FOCUS_NONE 0x00

View File

@ -43,6 +43,7 @@ public:
virtual nsresult HandleStartComposition(nsIDOMEvent* aCompositionEvent) = 0;
virtual nsresult HandleEndComposition(nsIDOMEvent* aCompositionEvent) = 0;
virtual nsresult HandleQueryComposition(nsIDOMEvent* aCompositionEvent) = 0;
};
#endif // nsIDOMCompositionListener_h__

View File

@ -1383,11 +1383,8 @@ nsEditor::DebugUnitTests(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed)
// The BeingComposition method is called from the Editor Composition event listeners.
//
NS_IMETHODIMP
nsEditor::BeginComposition(nsTextEventReply* aReply)
nsEditor::QueryComposition(nsTextEventReply* aReply)
{
#ifdef DEBUG_tague
printf("nsEditor::StartComposition\n");
#endif
nsresult result;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIDOMCharacterData> nodeAsText;
@ -1401,11 +1398,18 @@ nsEditor::BeginComposition(nsTextEventReply* aReply)
caretP->GetWindowRelativeCoordinates(aReply->mCursorPosition,aReply->mCursorIsCollapsed);
}
}
mInIMEMode = PR_TRUE;
return result;
}
NS_IMETHODIMP
nsEditor::BeginComposition(nsTextEventReply* aReply)
{
#ifdef DEBUG_tague
printf("nsEditor::StartComposition\n");
#endif
nsresult ret = QueryComposition(aReply);
mInIMEMode = PR_TRUE;
return ret;
}
NS_IMETHODIMP
nsEditor::EndComposition(void)

View File

@ -208,6 +208,7 @@ public:
/* ------------ nsIEditorIMESupport methods -------------- */
NS_IMETHOD BeginComposition(nsTextEventReply* aReply);
NS_IMETHOD QueryComposition(nsTextEventReply* aReply);
NS_IMETHOD SetCompositionString(const nsString& aCompositionString, nsIPrivateTextRangeList* aTextRangeList,nsTextEventReply* aReply);
NS_IMETHOD EndComposition(void);

View File

@ -901,6 +901,22 @@ nsTextEditorCompositionListener::HandleStartComposition(nsIDOMEvent* aCompositio
return mEditor->BeginComposition(eventReply);
}
nsresult
nsTextEditorCompositionListener::HandleQueryComposition(nsIDOMEvent* aCompositionEvent)
{
#ifdef DEBUG_IME
printf("nsTextEditorCompositionListener::HandleQueryComposition\n");
#endif
nsCOMPtr<nsIPrivateCompositionEvent> pCompositionEvent = do_QueryInterface(aCompositionEvent);
nsTextEventReply* eventReply;
if (!pCompositionEvent) return NS_ERROR_FAILURE;
nsresult rv = pCompositionEvent->GetCompositionReply(&eventReply);
if (NS_FAILED(rv)) return rv;
return mEditor->QueryComposition(eventReply);
}
nsresult
nsTextEditorCompositionListener::HandleEndComposition(nsIDOMEvent* aCompositionEvent)

View File

@ -132,6 +132,7 @@ public:
virtual nsresult HandleEvent(nsIDOMEvent* aEvent);
virtual nsresult HandleStartComposition(nsIDOMEvent* aCompositionEvent);
virtual nsresult HandleEndComposition(nsIDOMEvent* aCompositionEvent);
virtual nsresult HandleQueryComposition(nsIDOMEvent* aCompositionEvent);
/*END implementations of textevent handler interface*/
protected:

View File

@ -1383,11 +1383,8 @@ nsEditor::DebugUnitTests(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed)
// The BeingComposition method is called from the Editor Composition event listeners.
//
NS_IMETHODIMP
nsEditor::BeginComposition(nsTextEventReply* aReply)
nsEditor::QueryComposition(nsTextEventReply* aReply)
{
#ifdef DEBUG_tague
printf("nsEditor::StartComposition\n");
#endif
nsresult result;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIDOMCharacterData> nodeAsText;
@ -1401,11 +1398,18 @@ nsEditor::BeginComposition(nsTextEventReply* aReply)
caretP->GetWindowRelativeCoordinates(aReply->mCursorPosition,aReply->mCursorIsCollapsed);
}
}
mInIMEMode = PR_TRUE;
return result;
}
NS_IMETHODIMP
nsEditor::BeginComposition(nsTextEventReply* aReply)
{
#ifdef DEBUG_tague
printf("nsEditor::StartComposition\n");
#endif
nsresult ret = QueryComposition(aReply);
mInIMEMode = PR_TRUE;
return ret;
}
NS_IMETHODIMP
nsEditor::EndComposition(void)

View File

@ -208,6 +208,7 @@ public:
/* ------------ nsIEditorIMESupport methods -------------- */
NS_IMETHOD BeginComposition(nsTextEventReply* aReply);
NS_IMETHOD QueryComposition(nsTextEventReply* aReply);
NS_IMETHOD SetCompositionString(const nsString& aCompositionString, nsIPrivateTextRangeList* aTextRangeList,nsTextEventReply* aReply);
NS_IMETHOD EndComposition(void);

View File

@ -901,6 +901,22 @@ nsTextEditorCompositionListener::HandleStartComposition(nsIDOMEvent* aCompositio
return mEditor->BeginComposition(eventReply);
}
nsresult
nsTextEditorCompositionListener::HandleQueryComposition(nsIDOMEvent* aCompositionEvent)
{
#ifdef DEBUG_IME
printf("nsTextEditorCompositionListener::HandleQueryComposition\n");
#endif
nsCOMPtr<nsIPrivateCompositionEvent> pCompositionEvent = do_QueryInterface(aCompositionEvent);
nsTextEventReply* eventReply;
if (!pCompositionEvent) return NS_ERROR_FAILURE;
nsresult rv = pCompositionEvent->GetCompositionReply(&eventReply);
if (NS_FAILED(rv)) return rv;
return mEditor->QueryComposition(eventReply);
}
nsresult
nsTextEditorCompositionListener::HandleEndComposition(nsIDOMEvent* aCompositionEvent)

View File

@ -132,6 +132,7 @@ public:
virtual nsresult HandleEvent(nsIDOMEvent* aEvent);
virtual nsresult HandleStartComposition(nsIDOMEvent* aCompositionEvent);
virtual nsresult HandleEndComposition(nsIDOMEvent* aCompositionEvent);
virtual nsresult HandleQueryComposition(nsIDOMEvent* aCompositionEvent);
/*END implementations of textevent handler interface*/
protected:

View File

@ -53,11 +53,16 @@ public:
NS_IMETHOD SetCompositionString(const nsString& aCompositionString, nsIPrivateTextRangeList* aTextRange, nsTextEventReply* aReply) = 0;
/**
* BeginComposition() Handles the end of inline input composition.
* EndComposition() Handles the end of inline input composition.
*/
NS_IMETHOD EndComposition(void) = 0;
/**
* QueryComposition() Get the composition position
*/
NS_IMETHOD QueryComposition(nsTextEventReply *aReply) = 0;
};

View File

@ -317,7 +317,8 @@ NS_METHOD nsDOMEvent::GetEventReply(nsTextEventReply** aReply)
NS_METHOD nsDOMEvent::GetCompositionReply(nsTextEventReply** aReply)
{
if (mEvent->message==NS_COMPOSITION_START) {
if((mEvent->message==NS_COMPOSITION_START) ||
(mEvent->message==NS_COMPOSITION_QUERY)) {
*aReply = &(((nsCompositionEvent*)mEvent)->theReply);
return NS_OK;
}

View File

@ -821,6 +821,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
case NS_COMPOSITION_START:
case NS_COMPOSITION_END:
case NS_COMPOSITION_QUERY:
#if DEBUG_TAGUE
printf("DOM: got composition event\n");
#endif
@ -842,6 +843,9 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
if (aEvent->message==NS_COMPOSITION_END) {
ret = mCompositionListener->HandleEndComposition(*aDOMEvent);
}
if (aEvent->message==NS_COMPOSITION_QUERY) {
ret = mCompositionListener->HandleQueryComposition(*aDOMEvent);
}
}
NS_RELEASE(mCompositionListener);
}
@ -861,6 +865,12 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
correctSubType = PR_TRUE;
}
break;
case NS_COMPOSITION_QUERY:
subType = NS_EVENT_BITS_COMPOSITION_QUERY;
if (ls->mSubType & NS_EVENT_BITS_COMPOSITION_QUERY) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}

View File

@ -160,6 +160,7 @@ protected:
#define NS_EVENT_BITS_COMPOSITION_NONE 0x00
#define NS_EVENT_BITS_COMPOSITION_START 0x01
#define NS_EVENT_BITS_COMPOSITION_END 0x02
#define NS_EVENT_BITS_COMPOSITION_QUERY 0x04
//nsIDOMFocusListener
#define NS_EVENT_BITS_FOCUS_NONE 0x00

View File

@ -1688,7 +1688,8 @@ NS_IMETHODIMP nsViewManager :: DispatchEvent(nsGUIEvent *aEvent, nsEventStatus *
((nsTextEvent*)aEvent)->theReply.mCursorPosition.x=NSTwipsToIntPixels(((nsTextEvent*)aEvent)->theReply.mCursorPosition.x, t2p);
((nsTextEvent*)aEvent)->theReply.mCursorPosition.y=NSTwipsToIntPixels(((nsTextEvent*)aEvent)->theReply.mCursorPosition.y, t2p);
}
if (aEvent->message==NS_COMPOSITION_START) {
if((aEvent->message==NS_COMPOSITION_START) ||
(aEvent->message==NS_COMPOSITION_QUERY)) {
((nsCompositionEvent*)aEvent)->theReply.mCursorPosition.x=NSTwipsToIntPixels(((nsCompositionEvent*)aEvent)->theReply.mCursorPosition.x,t2p);
((nsCompositionEvent*)aEvent)->theReply.mCursorPosition.y=NSTwipsToIntPixels(((nsCompositionEvent*)aEvent)->theReply.mCursorPosition.y,t2p);
}

View File

@ -234,6 +234,7 @@ enum nsDragDropEventStatus {
#define NS_COMPOSITION_START 13
#define NS_COMPOSITION_END 14
#define NS_MOUSE_SCROLL_EVENT 15
#define NS_COMPOSITION_QUERY 16
/**
* GUI MESSAGES

View File

@ -70,6 +70,68 @@ PRUint32 nsWidget::sWidgetCount = 0;
// this is the nsWindow with the focus
nsWidget *nsWidget::focusWindow = NULL;
nsresult nsWidget::KillICSpotTimer ()
{
if(mICSpotTimer)
{
mICSpotTimer->Cancel();
NS_RELEASE(mICSpotTimer);
mICSpotTimer = nsnull;
}
return NS_OK;
}
nsresult nsWidget::PrimeICSpotTimer ()
{
KillICSpotTimer();
nsresult err = NS_NewTimer(&mICSpotTimer);
if(NS_FAILED(err))
return err;
mICSpotTimer->Init(ICSpotCallback, this, 1000);
return NS_OK;
}
void nsWidget::ICSpotCallback(nsITimer * aTimer, void * aClosure)
{
nsWidget *widget= NS_REINTERPRET_CAST(nsWidget*, aClosure);
if( ! widget) return;
nsresult res = widget->UpdateICSpot();
if(NS_SUCCEEDED(res))
{
widget->PrimeICSpotTimer();
}
}
nsresult nsWidget::UpdateICSpot()
{
// set spot location
nsCompositionEvent compEvent;
nsEventStatus status;
compEvent.widget = (nsWidget*)this;
compEvent.point.x = 0;
compEvent.point.y = 0;
compEvent.time = 0;
compEvent.message = NS_COMPOSITION_QUERY;
compEvent.eventStructType = NS_COMPOSITION_QUERY;
compEvent.compositionMessage = NS_COMPOSITION_QUERY;
static gint oldx =0;
static gint oldy =0;
compEvent.theReply.mCursorPosition.x=-1;
compEvent.theReply.mCursorPosition.y=-1;
DispatchEvent(&compEvent, status);
// set SpotLocation
if((compEvent.theReply.mCursorPosition.x == -1) &&
(compEvent.theReply.mCursorPosition.y == -1))
return NS_ERROR_ABORT;
if((compEvent.theReply.mCursorPosition.x != oldx)||
(compEvent.theReply.mCursorPosition.y != oldy))
{
SetXICSpotLocation(compEvent.theReply.mCursorPosition);
oldx = compEvent.theReply.mCursorPosition.x;
oldy = compEvent.theReply.mCursorPosition.y;
}
return NS_OK;
}
nsIRollupListener *nsWidget::gRollupListener = nsnull;
nsIWidget *nsWidget::gRollupWidget = nsnull;
PRBool nsWidget::gRollupConsumeRollupEvent = PR_FALSE;
@ -148,6 +210,8 @@ nsWidget::nsWidget()
mIMECompositionUniString = nsnull;
mIMECompositionUniStringSize = 0;
mListenForResizes = PR_FALSE;
mICSpotTimer = nsnull;
mHasFocus = PR_FALSE;
if (mGDKHandlerInstalled == PR_FALSE) {
mGDKHandlerInstalled = PR_TRUE;
@ -159,6 +223,7 @@ nsWidget::nsWidget()
nsWidget::~nsWidget()
{
KillICSpotTimer();
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
printf("nsWidget::~nsWidget:%p\n", this);
@ -2008,21 +2073,7 @@ nsWidget::OnFocusInSignal(GdkEventFocus * aGdkFocusEvent)
if (gdkWindow)
{
gdk_im_begin ((GdkIC*)mIC, gdkWindow);
#if 0
// set spot location
nsCompositionEvent compEvent;
nsEventStatus status;
compEvent.widget = (nsWidget*)this;
compEvent.point.x = 0;
compEvent.point.y = 0;
compEvent.time = 0;
compEvent.message = NS_COMPOSITION_START;
compEvent.eventStructType = NS_COMPOSITION_START;
compEvent.compositionMessage = NS_COMPOSITION_START;
DispatchEvent(&compEvent, status);
// set SpotLocation
SetXICSpotLocation(compEvent.theReply.mCursorPosition);
#endif
PrimeICSpotTimer();
}
else
{
@ -2079,6 +2130,8 @@ nsWidget::OnFocusOutSignal(GdkEventFocus * aGdkFocusEvent)
}
if (mIC)
{
KillICSpotTimer();
GdkWindow *gdkWindow = (GdkWindow*) GetNativeData(NS_NATIVE_WINDOW);
if (gdkWindow)
{

View File

@ -40,6 +40,7 @@ class nsIToolkit;
#include <gdk/gdkprivate.h>
#include "gtkmozbox.h"
#include "nsITimer.h"
#define NSRECT_TO_GDKRECT(ns,gdk) \
PR_BEGIN_MACRO \
@ -416,6 +417,14 @@ protected:
static nsIWidget *gRollupWidget;
static PRBool gRollupConsumeRollupEvent;
nsITimer* mICSpotTimer;
static void ICSpotCallback(nsITimer* aTimer, void* aClosure);
nsresult UpdateICSpot();
public:
nsresult KillICSpotTimer();
nsresult PrimeICSpotTimer();
private:
PRBool mIsDragDest;
static nsILookAndFeel *sLookAndFeel;

View File

@ -585,6 +585,7 @@ nsWindow::SetFocus(void)
if (mIC)
{
GdkWindow *gdkWindow = (GdkWindow*) focusWindow->GetNativeData(NS_NATIVE_WINDOW);
focusWindow->KillICSpotTimer();
if (gdkWindow)
{
gdk_im_end();
@ -656,6 +657,7 @@ nsWindow::SetFocus(void)
if (gdkWindow)
{
gdk_im_begin ((GdkIC*)mIC, gdkWindow);
PrimeICSpotTimer();
}
else
{
@ -718,6 +720,7 @@ nsWindow::OnFocusInSignal(GdkEventFocus * aGdkFocusEvent)
if (gdkWindow)
{
gdk_im_begin ((GdkIC*)mIC, gdkWindow);
PrimeICSpotTimer();
}
else
{
@ -773,6 +776,7 @@ nsWindow::OnFocusOutSignal(GdkEventFocus * aGdkFocusEvent)
if (mIC)
{
GdkWindow *gdkWindow = (GdkWindow*) GetNativeData(NS_NATIVE_WINDOW);
KillICSpotTimer();
if (gdkWindow)
{
gdk_im_end();