Skip to content

Commit

Permalink
Update cursor location when key pressed if the client window was moved
Browse files Browse the repository at this point in the history
In some GTK applications, when input window is visible and the user moves
the application wdinow to another location, the cursor location will not
be updated. Then if the user presses some new keys, the input window will
not move to the new cursor location automatically. So it's necessary to
update the cursor location when key pressed if the client window was moved.
  • Loading branch information
kingysu committed Jun 17, 2024
1 parent 2b78dfe commit 0d24319
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 14 deletions.
26 changes: 19 additions & 7 deletions gtk2/fcitximcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ struct _FcitxIMContext {
GtkIMContext parent;

GdkWindow *client_window;
gint client_window_x;
gint client_window_y;
gulong button_press_signal;
bool has_rect;
GdkRectangle area;
Expand Down Expand Up @@ -299,6 +301,8 @@ static void fcitx_im_context_class_fini(FcitxIMContextClass *, gpointer) {
}

static void fcitx_im_context_init(FcitxIMContext *context, gpointer) {
context->client_window_x = -1;
context->client_window_y = -1;
context->client = NULL;
context->has_rect = FALSE;
context->area.x = -1;
Expand Down Expand Up @@ -509,14 +513,13 @@ static gboolean fcitx_im_context_filter_keypress(GtkIMContext *context,
if (fcitxcontext->client_window == NULL && event->window != NULL) {
gtk_im_context_set_client_window((GtkIMContext *)fcitxcontext,
event->window);

/* set_cursor_location_internal() will get origin from X server,
* it blocks UI. So delay it to idle callback. */
gdk_threads_add_idle_full(
G_PRIORITY_DEFAULT_IDLE,
(GSourceFunc)_set_cursor_location_internal,
g_object_ref(fcitxcontext), (GDestroyNotify)g_object_unref);
}

/* set_cursor_location_internal() will get origin from X server,
* it blocks UI. So delay it to idle callback. */
gdk_threads_add_idle_full(
G_PRIORITY_DEFAULT_IDLE, (GSourceFunc)_set_cursor_location_internal,
g_object_ref(fcitxcontext), (GDestroyNotify)g_object_unref);
}

if (event->state & (guint64)HandledMask) {
Expand Down Expand Up @@ -886,6 +889,15 @@ static gboolean _set_cursor_location_internal(FcitxIMContext *fcitxcontext) {
}
#endif
}

if (area.x == fcitxcontext->client_window_x &&
area.y == fcitxcontext->client_window_y) {
return FALSE;
}

fcitxcontext->client_window_x = area.x;
fcitxcontext->client_window_y = area.y;

int scale = 1;
area.x *= scale;
area.y *= scale;
Expand Down
26 changes: 19 additions & 7 deletions gtk3/fcitximcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ struct _FcitxIMContext {
GtkIMContext parent;

GdkWindow *client_window;
gint client_window_x;
gint client_window_y;
gulong button_press_signal;
bool has_rect;
GdkRectangle area;
Expand Down Expand Up @@ -319,6 +321,8 @@ static void fcitx_im_context_class_fini(FcitxIMContextClass *, gpointer) {
}

static void fcitx_im_context_init(FcitxIMContext *context, gpointer) {
context->client_window_x = -1;
context->client_window_y = -1;
context->client = NULL;
context->has_rect = FALSE;
context->area.x = -1;
Expand Down Expand Up @@ -567,14 +571,13 @@ static gboolean fcitx_im_context_filter_keypress(GtkIMContext *context,
if (fcitxcontext->client_window == NULL && event->window != NULL) {
gtk_im_context_set_client_window((GtkIMContext *)fcitxcontext,
event->window);

/* set_cursor_location_internal() will get origin from X server,
* it blocks UI. So delay it to idle callback. */
gdk_threads_add_idle_full(
G_PRIORITY_DEFAULT_IDLE,
(GSourceFunc)_set_cursor_location_internal,
g_object_ref(fcitxcontext), (GDestroyNotify)g_object_unref);
}

/* set_cursor_location_internal() will get origin from X server,
* it blocks UI. So delay it to idle callback. */
gdk_threads_add_idle_full(
G_PRIORITY_DEFAULT_IDLE, (GSourceFunc)_set_cursor_location_internal,
g_object_ref(fcitxcontext), (GDestroyNotify)g_object_unref);
}

if (event->state & (guint64)HandledMask) {
Expand Down Expand Up @@ -977,6 +980,15 @@ static gboolean _set_cursor_location_internal(FcitxIMContext *fcitxcontext) {
gdk_window_get_root_coords(fcitxcontext->client_window, area.x, area.y,
&area.x, &area.y);
}

if (area.x == fcitxcontext->client_window_x &&
area.y == fcitxcontext->client_window_y) {
return FALSE;
}

fcitxcontext->client_window_x = area.x;
fcitxcontext->client_window_y = area.y;

int scale = 1;
#if GTK_CHECK_VERSION(3, 10, 0)
scale = gdk_window_get_scale_factor(fcitxcontext->client_window);
Expand Down

0 comments on commit 0d24319

Please sign in to comment.