mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
247 lines
8.3 KiB
Diff
247 lines
8.3 KiB
Diff
From 916a85ecb934034c66c58a66befab5713ea9c28e Mon Sep 17 00:00:00 2001
|
|
From: Felix Yan <felixonmars@gmail.com>
|
|
Date: Tue, 23 Sep 2014 23:22:17 +0800
|
|
Subject: [PATCH] winex11.drv: Update a candidate window's position with
|
|
over-the-spot style. (try 2)
|
|
|
|
In the current implementation, the candidate window position of a input
|
|
method is fixed because XNSpotLocation isn't updated after an input
|
|
context (XIC) is created in X11DRV_CreateIC().
|
|
X11DRV_UpdateCandidatePos() in this patch updates the position. You can
|
|
see the change of a position with ibus, scim or fcitx when input style
|
|
is set to "over the spot" in the registry key:
|
|
|
|
[HKEY_CURRENT_USER\Software\Wine\X11 Driver]
|
|
"InputStyle"="OverTheSpot"
|
|
|
|
This patch was based on the original work by Muneyuki Noguchi, and
|
|
received a lot of help from Sebastian Lackner.
|
|
---
|
|
dlls/user32/caret.c | 4 ++
|
|
dlls/user32/driver.c | 17 ++++++++
|
|
dlls/user32/user_private.h | 2 +
|
|
dlls/winex11.drv/winex11.drv.spec | 1 +
|
|
dlls/winex11.drv/xim.c | 72 ++++++++++++++++++++++++++++++-
|
|
5 files changed, 95 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/dlls/user32/caret.c b/dlls/user32/caret.c
|
|
index 2da7e02ca1a..1dd3ff29de4 100644
|
|
--- a/dlls/user32/caret.c
|
|
+++ b/dlls/user32/caret.c
|
|
@@ -27,6 +27,8 @@
|
|
#include "winbase.h"
|
|
#include "wingdi.h"
|
|
#include "winuser.h"
|
|
+#include "user_private.h"
|
|
+
|
|
#include "wine/server.h"
|
|
#include "wine/debug.h"
|
|
|
|
@@ -274,6 +276,7 @@ BOOL WINAPI SetCaretPos( INT x, INT y )
|
|
r.left = x;
|
|
r.top = y;
|
|
CARET_DisplayCaret( hwnd, &r );
|
|
+ USER_Driver->pUpdateCandidatePos( hwnd, &r );
|
|
SetSystemTimer( hwnd, TIMERID, Caret.timeout, CARET_Callback );
|
|
}
|
|
return ret;
|
|
@@ -352,6 +355,7 @@ BOOL WINAPI ShowCaret( HWND hwnd )
|
|
if (ret && (hidden == 1)) /* hidden was 1 so it's now 0 */
|
|
{
|
|
CARET_DisplayCaret( hwnd, &r );
|
|
+ USER_Driver->pUpdateCandidatePos( hwnd, &r );
|
|
SetSystemTimer( hwnd, TIMERID, Caret.timeout, CARET_Callback );
|
|
}
|
|
return ret;
|
|
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
|
|
index 36438fa44c8..4a52900feb6 100644
|
|
--- a/dlls/user32/driver.c
|
|
+++ b/dlls/user32/driver.c
|
|
@@ -149,6 +149,7 @@ static const USER_DRIVER *load_driver(void)
|
|
GET_USER_FUNC(WindowPosChanging);
|
|
GET_USER_FUNC(WindowPosChanged);
|
|
GET_USER_FUNC(SystemParametersInfo);
|
|
+ GET_USER_FUNC(UpdateCandidatePos);
|
|
GET_USER_FUNC(ThreadDetach);
|
|
#undef GET_USER_FUNC
|
|
}
|
|
@@ -405,6 +406,10 @@ static BOOL CDECL nulldrv_SystemParametersInfo( UINT action, UINT int_param, voi
|
|
return FALSE;
|
|
}
|
|
|
|
+static void CDECL nulldrv_UpdateCandidatePos( HWND hwnd, const RECT *caret_rect )
|
|
+{
|
|
+}
|
|
+
|
|
static void CDECL nulldrv_ThreadDetach( void )
|
|
{
|
|
}
|
|
@@ -461,10 +466,13 @@ static USER_DRIVER null_driver =
|
|
nulldrv_WindowPosChanged,
|
|
/* system parameters */
|
|
nulldrv_SystemParametersInfo,
|
|
+ /* candidate pos functions */
|
|
+ nulldrv_UpdateCandidatePos,
|
|
/* thread management */
|
|
nulldrv_ThreadDetach
|
|
};
|
|
|
|
+/* this line exists so that git won't apply this diff in the wrong place */
|
|
|
|
/**********************************************************************
|
|
* Lazy loading user driver
|
|
@@ -612,6 +620,11 @@ static BOOL CDECL loaderdrv_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDW
|
|
return load_driver()->pUpdateLayeredWindow( hwnd, info, window_rect );
|
|
}
|
|
|
|
+static void CDECL loaderdrv_UpdateCandidatePos( HWND hwnd, const RECT *caret_rect )
|
|
+{
|
|
+ load_driver()->pUpdateCandidatePos( hwnd, caret_rect );
|
|
+}
|
|
+
|
|
static USER_DRIVER lazy_load_driver =
|
|
{
|
|
/* keyboard functions */
|
|
@@ -664,6 +677,10 @@ static USER_DRIVER lazy_load_driver =
|
|
nulldrv_WindowPosChanged,
|
|
/* system parameters */
|
|
nulldrv_SystemParametersInfo,
|
|
+ /* candidate pos functions */
|
|
+ loaderdrv_UpdateCandidatePos,
|
|
/* thread management */
|
|
nulldrv_ThreadDetach
|
|
};
|
|
+
|
|
+/* this line exists so that git won't apply this diff in the wrong place */
|
|
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
|
|
index 1c7ac3355bc..f9d01fbb406 100644
|
|
--- a/dlls/user32/user_private.h
|
|
+++ b/dlls/user32/user_private.h
|
|
@@ -111,6 +111,8 @@ typedef struct tagUSER_DRIVER {
|
|
void (CDECL *pWindowPosChanged)(HWND,HWND,UINT,const RECT *,const RECT *,const RECT *,const RECT *,struct window_surface*);
|
|
/* system parameters */
|
|
BOOL (CDECL *pSystemParametersInfo)(UINT,UINT,void*,UINT);
|
|
+ /* candidate pos functions */
|
|
+ void (CDECL *pUpdateCandidatePos)(HWND,const RECT *);
|
|
/* thread management */
|
|
void (CDECL *pThreadDetach)(void);
|
|
} USER_DRIVER;
|
|
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
|
|
index eb5f7cecc6c..108bf98f357 100644
|
|
--- a/dlls/winex11.drv/winex11.drv.spec
|
|
+++ b/dlls/winex11.drv/winex11.drv.spec
|
|
@@ -43,6 +43,7 @@
|
|
@ cdecl WindowPosChanging(long long long ptr ptr ptr ptr) X11DRV_WindowPosChanging
|
|
@ cdecl WindowPosChanged(long long long ptr ptr ptr ptr ptr) X11DRV_WindowPosChanged
|
|
@ cdecl SystemParametersInfo(long long ptr long) X11DRV_SystemParametersInfo
|
|
+@ cdecl UpdateCandidatePos(long ptr) X11DRV_UpdateCandidatePos
|
|
@ cdecl ThreadDetach() X11DRV_ThreadDetach
|
|
|
|
# WinTab32
|
|
diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c
|
|
index 44fe62e9006..a4567ce26a2 100644
|
|
--- a/dlls/winex11.drv/xim.c
|
|
+++ b/dlls/winex11.drv/xim.c
|
|
@@ -32,6 +32,7 @@
|
|
#include "x11drv.h"
|
|
#include "imm.h"
|
|
#include "wine/debug.h"
|
|
+#include "wine/server.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(xim);
|
|
|
|
@@ -458,6 +459,48 @@ static BOOL X11DRV_DestroyIC(XIC xic, XPointer p, XPointer data)
|
|
return TRUE;
|
|
}
|
|
|
|
+/***********************************************************************
|
|
+ * X11DRV_UpdateCandidatePos
|
|
+ */
|
|
+void X11DRV_UpdateCandidatePos( HWND hwnd, const RECT *caret_rect )
|
|
+{
|
|
+ if (ximStyle & XIMPreeditPosition)
|
|
+ {
|
|
+ struct x11drv_win_data *data;
|
|
+ HWND parent;
|
|
+
|
|
+ for (parent = hwnd; parent && parent != GetDesktopWindow(); parent = GetAncestor( parent, GA_PARENT ))
|
|
+ {
|
|
+ if (!(data = get_win_data( parent ))) continue;
|
|
+ if (data->xic)
|
|
+ {
|
|
+ XVaNestedList preedit;
|
|
+ XPoint xpoint;
|
|
+ POINT pt;
|
|
+
|
|
+ pt.x = caret_rect->left;
|
|
+ pt.y = caret_rect->bottom;
|
|
+
|
|
+ if (hwnd != data->hwnd)
|
|
+ MapWindowPoints( hwnd, data->hwnd, &pt, 1 );
|
|
+
|
|
+ if (GetWindowLongW( data->hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL)
|
|
+ pt.x = data->client_rect.right - data->client_rect.left - 1 - pt.x;
|
|
+
|
|
+ xpoint.x = pt.x + data->client_rect.left - data->whole_rect.left;
|
|
+ xpoint.y = pt.y + data->client_rect.top - data->whole_rect.top;
|
|
+
|
|
+ preedit = XVaCreateNestedList( 0, XNSpotLocation, &xpoint, NULL );
|
|
+ if (preedit)
|
|
+ {
|
|
+ XSetICValues( data->xic, XNPreeditAttributes, preedit, NULL );
|
|
+ XFree( preedit );
|
|
+ }
|
|
+ }
|
|
+ release_win_data( data );
|
|
+ }
|
|
+ }
|
|
+}
|
|
|
|
XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data)
|
|
{
|
|
@@ -485,7 +528,7 @@ XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data)
|
|
XNDestroyCallback, &destroy,
|
|
NULL);
|
|
data->xic = xic;
|
|
- return xic;
|
|
+ goto return_xic;
|
|
}
|
|
|
|
/* create callbacks */
|
|
@@ -583,5 +626,32 @@ XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data)
|
|
if (status != NULL)
|
|
XFree(status);
|
|
|
|
+return_xic:
|
|
+ if (xic != NULL && (ximStyle & XIMPreeditPosition))
|
|
+ {
|
|
+ SERVER_START_REQ( set_caret_info )
|
|
+ {
|
|
+ req->flags = 0; /* don't set anything */
|
|
+ req->handle = 0;
|
|
+ req->x = 0;
|
|
+ req->y = 0;
|
|
+ req->hide = 0;
|
|
+ req->state = 0;
|
|
+ if (!wine_server_call_err( req ))
|
|
+ {
|
|
+ HWND hwnd;
|
|
+ RECT r;
|
|
+
|
|
+ hwnd = wine_server_ptr_handle( reply->full_handle );
|
|
+ r.left = reply->old_rect.left;
|
|
+ r.top = reply->old_rect.top;
|
|
+ r.right = reply->old_rect.right;
|
|
+ r.bottom = reply->old_rect.bottom;
|
|
+ X11DRV_UpdateCandidatePos( hwnd, &r );
|
|
+ }
|
|
+ }
|
|
+ SERVER_END_REQ;
|
|
+ }
|
|
+
|
|
return xic;
|
|
}
|
|
--
|
|
2.30.2
|
|
|