[GB.GTK]
* BUG: Fix input method handling. * NEW: Application_KeyPress global event handler has been implemented. git-svn-id: svn://localhost/gambas/trunk@2335 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
parent
550ead384c
commit
a309dffd70
8 changed files with 91 additions and 40 deletions
|
@ -36,6 +36,8 @@
|
|||
#include "gmouse.h"
|
||||
#include "gmainwindow.h"
|
||||
|
||||
//#define DEBUG_IM 1
|
||||
|
||||
/*************************************************************************
|
||||
|
||||
gKey
|
||||
|
@ -46,7 +48,7 @@ bool gKey::_valid = false;
|
|||
bool gKey::_no_input_method = false;
|
||||
GdkEventKey gKey::_event;
|
||||
GtkIMContext *gKey::_im_context = NULL;
|
||||
GtkWidget *gKey::_im_widget = NULL;
|
||||
gControl *gKey::_im_control = NULL;
|
||||
char *_im_text = NULL;
|
||||
|
||||
const char *gKey::text()
|
||||
|
@ -117,7 +119,7 @@ void gKey::disable()
|
|||
g_free(_event.string);
|
||||
}
|
||||
|
||||
bool gKey::enable(GtkWidget *widget, GdkEventKey *event)
|
||||
bool gKey::enable(gControl *control, GdkEventKey *event)
|
||||
{
|
||||
bool filter;
|
||||
|
||||
|
@ -130,11 +132,15 @@ bool gKey::enable(GtkWidget *widget, GdkEventKey *event)
|
|||
_valid = true;
|
||||
_event = *event;
|
||||
|
||||
if (_event.type == GDK_KEY_PRESS && !_no_input_method && widget == _im_widget)
|
||||
if (_event.type == GDK_KEY_PRESS && !_no_input_method && control == _im_control)
|
||||
{
|
||||
//fprintf(stderr, "gKey::enable: event->string = '%s'\n", event->string);
|
||||
#if DEBUG_IM
|
||||
fprintf(stderr, "gKey::enable: event->string = '%s'\n", event->string);
|
||||
#endif
|
||||
filter = gtk_im_context_filter_keypress(_im_context, &_event);
|
||||
//fprintf(stderr, "gKey::enable: filter -> %d event->string = '%s'\n", filter, event->string);
|
||||
#if DEBUG_IM
|
||||
fprintf(stderr, "gKey::enable: filter -> %d event->string = '%s'\n", filter, event->string);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
filter = false;
|
||||
|
@ -142,14 +148,17 @@ bool gKey::enable(GtkWidget *widget, GdkEventKey *event)
|
|||
if (filter && _im_text)
|
||||
{
|
||||
_event.string = g_strdup(_im_text);
|
||||
filter = false;
|
||||
_event.keyval = 0;
|
||||
filter = false;
|
||||
}
|
||||
else
|
||||
_event.string = g_strdup(_event.string);
|
||||
|
||||
if (!filter)
|
||||
{
|
||||
//#if DEBUG_IM
|
||||
//fprintf(stderr, "gKey::enable: gtk_im_context_reset\n");
|
||||
//#endif
|
||||
//gtk_im_context_reset(_im_context);
|
||||
if (_im_text)
|
||||
{
|
||||
|
@ -164,7 +173,9 @@ bool gKey::enable(GtkWidget *widget, GdkEventKey *event)
|
|||
|
||||
static void cb_im_commit(GtkIMContext *context, const gchar *str, gpointer pointer)
|
||||
{
|
||||
//fprintf(stderr, "cb_im_commit: %s\n", str);
|
||||
#if DEBUG_IM
|
||||
fprintf(stderr, "cb_im_commit: %s\n", str);
|
||||
#endif
|
||||
|
||||
if (_im_text)
|
||||
g_free(_im_text);
|
||||
|
@ -188,30 +199,34 @@ void gKey::exit()
|
|||
|
||||
void gKey::setActiveControl(gControl *control)
|
||||
{
|
||||
if (_im_widget)
|
||||
if (_im_control)
|
||||
{
|
||||
//fprintf(stderr, "gtm_im_context_focus_out\n");
|
||||
if (!_no_input_method)
|
||||
{
|
||||
#if DEBUG_IM
|
||||
fprintf(stderr, "gtm_im_context_focus_out\n");
|
||||
#endif
|
||||
gtk_im_context_set_client_window (_im_context, 0);
|
||||
gtk_im_context_focus_out(_im_context);
|
||||
}
|
||||
_im_widget = NULL;
|
||||
_im_control = NULL;
|
||||
_no_input_method = false;
|
||||
}
|
||||
|
||||
if (control)
|
||||
{
|
||||
_im_widget = control->widget;
|
||||
_im_control = control;
|
||||
_no_input_method = control->noInputMethod();
|
||||
|
||||
if (!_no_input_method)
|
||||
{
|
||||
gtk_im_context_set_client_window (_im_context, _im_widget->window);
|
||||
gtk_im_context_set_client_window (_im_context, _im_control->widget->window);
|
||||
gtk_im_context_focus_in(_im_context);
|
||||
gtk_im_context_reset(_im_context);
|
||||
#if DEBUG_IM
|
||||
fprintf(stderr, "gtm_im_context_focus_in\n");
|
||||
#endif
|
||||
}
|
||||
//fprintf(stderr, "gtm_im_context_focus_in\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,11 +431,15 @@ static void gambas_handle_event(GdkEvent *event)
|
|||
|
||||
control = gDesktop::activeControl();
|
||||
|
||||
gKey::enable(widget, &event->key);
|
||||
if (control->onKeyEvent)
|
||||
if (!gKey::enable(control, &event->key))
|
||||
{
|
||||
//fprintf(stderr, "gEvent_KeyPress on %p %s\n", control, control->name());
|
||||
cancel = control->onKeyEvent(control, gEvent_KeyPress);
|
||||
if (gApplication::onKeyEvent)
|
||||
cancel = gApplication::onKeyEvent(gEvent_KeyPress);
|
||||
if (!cancel && control->onKeyEvent)
|
||||
{
|
||||
//fprintf(stderr, "gEvent_KeyPress on %p %s\n", control, control->name());
|
||||
cancel = control->onKeyEvent(control, gEvent_KeyPress);
|
||||
}
|
||||
}
|
||||
gKey::disable();
|
||||
|
||||
|
@ -459,8 +478,8 @@ static void gambas_handle_event(GdkEvent *event)
|
|||
|
||||
control = gDesktop::activeControl();
|
||||
|
||||
gKey::enable(widget, &event->key);
|
||||
control->emit(SIGNAL(control->onKeyEvent), gEvent_KeyRelease);
|
||||
if (!gKey::enable(control, &event->key))
|
||||
control->emit(SIGNAL(control->onKeyEvent), gEvent_KeyRelease);
|
||||
gKey::disable();
|
||||
|
||||
if (event->key.keyval == GDK_Escape)
|
||||
|
@ -505,6 +524,7 @@ void *gApplication::_loop_owner = 0;
|
|||
GtkWindowGroup *gApplication::_group = NULL;
|
||||
gControl *gApplication::_enter = NULL;
|
||||
gControl *gApplication::_leave = NULL;
|
||||
bool (*gApplication::onKeyEvent)(int) = NULL;
|
||||
|
||||
GtkTooltips* gApplication::tipHandle()
|
||||
{
|
||||
|
|
|
@ -63,6 +63,8 @@ public:
|
|||
static GtkWindowGroup *enterGroup();
|
||||
static void exitGroup(GtkWindowGroup *oldGroup);
|
||||
|
||||
static bool (*onKeyEvent)(int type);
|
||||
|
||||
//"Private"
|
||||
static GtkTooltips *tipHandle();
|
||||
static bool _busy;
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
|
||||
//"Private"
|
||||
static void disable();
|
||||
static bool enable(GtkWidget *w, GdkEventKey *e);
|
||||
static bool enable(gControl *control, GdkEventKey *e);
|
||||
static void init();
|
||||
static void exit();
|
||||
|
||||
|
@ -50,7 +50,7 @@ private:
|
|||
static GdkEventKey _event;
|
||||
static bool _valid;
|
||||
static GtkIMContext *_im_context;
|
||||
static GtkWidget *_im_widget;
|
||||
static gControl *_im_control;
|
||||
static bool _no_input_method;
|
||||
};
|
||||
|
||||
|
|
|
@ -76,7 +76,6 @@ gTextArea::gTextArea(gContainer *parent) : gControl(parent)
|
|||
|
||||
have_cursor = true;
|
||||
use_base = true;
|
||||
no_input_method = true;
|
||||
|
||||
onChange = 0;
|
||||
onCursor = 0;
|
||||
|
|
|
@ -56,8 +56,6 @@ gTextBox::gTextBox(gContainer *parent, bool combo) : gControl(parent)
|
|||
initEntry();
|
||||
}
|
||||
|
||||
no_input_method = true;
|
||||
|
||||
onChange = NULL;
|
||||
onActivate = NULL;
|
||||
}
|
||||
|
|
|
@ -1263,7 +1263,7 @@ void gTree::setSorted(bool v)
|
|||
return;
|
||||
|
||||
_sorted = v;
|
||||
_sort_column = v ? (view ? 0 : 1) : -1;
|
||||
_sort_column = v ? 0 : -1;
|
||||
updateSort();
|
||||
}
|
||||
|
||||
|
|
|
@ -81,12 +81,12 @@ static void my_wait(int duration);
|
|||
static void my_post(void);
|
||||
static int my_loop();
|
||||
static void my_watch(int fd, int type, void *callback, intptr_t param);
|
||||
bool post_Check=false;
|
||||
|
||||
|
||||
int MAIN_scale = 8;
|
||||
static bool post_Check=false;
|
||||
|
||||
static bool _application_keypress = false;
|
||||
static GB_FUNCTION _application_keypress_func;
|
||||
|
||||
int MAIN_scale = 0;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
@ -291,6 +291,12 @@ void my_quit (void)
|
|||
|
||||
}
|
||||
|
||||
static bool global_key_event_handler(int type)
|
||||
{
|
||||
GB.Call(&_application_keypress_func, 0, FALSE);
|
||||
return GB.Stopped();
|
||||
}
|
||||
|
||||
static void my_main(int *argc, char **argv)
|
||||
{
|
||||
gApplication::init(argc, &argv);
|
||||
|
@ -300,6 +306,12 @@ static void my_main(int *argc, char **argv)
|
|||
#ifdef GDK_WINDOWING_X11
|
||||
X11_init(gdk_x11_display_get_xdisplay(gdk_display_get_default()), gdk_x11_get_default_root_xwindow());
|
||||
#endif
|
||||
|
||||
if (GB.GetFunction(&_application_keypress_func, (void *)GB.FindClass(GB.Application.Startup()), "Application_KeyPress", "", "") == 0)
|
||||
{
|
||||
_application_keypress = true;
|
||||
gApplication::onKeyEvent = global_key_event_handler;
|
||||
}
|
||||
}
|
||||
|
||||
/*static void raise_timer(GB_TIMER *timer)
|
||||
|
|
|
@ -313,18 +313,38 @@ MyApplication::MyApplication(int &argc, char **argv)
|
|||
|
||||
static bool QT_EventFilter(QEvent *e)
|
||||
{
|
||||
QKeyEvent *kevent = (QKeyEvent *)e;
|
||||
bool cancel;
|
||||
|
||||
if (!_application_keypress)
|
||||
return false;
|
||||
|
||||
CKEY_clear(true);
|
||||
if (e->type() == QEvent::KeyPress)
|
||||
{
|
||||
QKeyEvent *kevent = (QKeyEvent *)e;
|
||||
|
||||
GB.FreeString(&CKEY_info.text);
|
||||
GB.NewString(&CKEY_info.text, QT_ToUTF8(kevent->text()), 0);
|
||||
CKEY_info.state = kevent->modifiers();
|
||||
CKEY_info.code = kevent->key();
|
||||
CKEY_clear(true);
|
||||
|
||||
GB.FreeString(&CKEY_info.text);
|
||||
GB.NewString(&CKEY_info.text, QT_ToUTF8(kevent->text()), 0);
|
||||
CKEY_info.state = kevent->modifiers();
|
||||
CKEY_info.code = kevent->key();
|
||||
|
||||
}
|
||||
else if (e->type() == QEvent::InputMethod)
|
||||
{
|
||||
QInputMethodEvent *imevent = (QInputMethodEvent *)e;
|
||||
|
||||
if (!imevent->commitString().isEmpty())
|
||||
{
|
||||
CKEY_clear(true);
|
||||
|
||||
GB.FreeString(&CKEY_info.text);
|
||||
//qDebug("IMEnd: %s", imevent->text().latin1());
|
||||
GB.NewString(&CKEY_info.text, QT_ToUTF8(imevent->commitString()), 0);
|
||||
CKEY_info.state = 0;
|
||||
CKEY_info.code = 0;
|
||||
}
|
||||
}
|
||||
|
||||
GB.Call(&_application_keypress_func, 0, FALSE);
|
||||
cancel = GB.Stopped();
|
||||
|
@ -346,7 +366,7 @@ bool MyApplication::eventFilter(QObject *o, QEvent *e)
|
|||
{
|
||||
if (o->isWidgetType())
|
||||
{
|
||||
if (e->type() == QEvent::KeyPress)
|
||||
if ((e->spontaneous() && e->type() == QEvent::KeyPress) || e->type() == QEvent::InputMethod)
|
||||
{
|
||||
if (QT_EventFilter(e))
|
||||
return true;
|
||||
|
|
Loading…
Reference in a new issue