* 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:
Benoît Minisini 2009-09-14 01:50:48 +00:00
parent 550ead384c
commit a309dffd70
8 changed files with 91 additions and 40 deletions

View file

@ -36,6 +36,8 @@
#include "gmouse.h" #include "gmouse.h"
#include "gmainwindow.h" #include "gmainwindow.h"
//#define DEBUG_IM 1
/************************************************************************* /*************************************************************************
gKey gKey
@ -46,7 +48,7 @@ bool gKey::_valid = false;
bool gKey::_no_input_method = false; bool gKey::_no_input_method = false;
GdkEventKey gKey::_event; GdkEventKey gKey::_event;
GtkIMContext *gKey::_im_context = NULL; GtkIMContext *gKey::_im_context = NULL;
GtkWidget *gKey::_im_widget = NULL; gControl *gKey::_im_control = NULL;
char *_im_text = NULL; char *_im_text = NULL;
const char *gKey::text() const char *gKey::text()
@ -117,7 +119,7 @@ void gKey::disable()
g_free(_event.string); g_free(_event.string);
} }
bool gKey::enable(GtkWidget *widget, GdkEventKey *event) bool gKey::enable(gControl *control, GdkEventKey *event)
{ {
bool filter; bool filter;
@ -130,11 +132,15 @@ bool gKey::enable(GtkWidget *widget, GdkEventKey *event)
_valid = true; _valid = true;
_event = *event; _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); 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 else
filter = false; filter = false;
@ -142,14 +148,17 @@ bool gKey::enable(GtkWidget *widget, GdkEventKey *event)
if (filter && _im_text) if (filter && _im_text)
{ {
_event.string = g_strdup(_im_text); _event.string = g_strdup(_im_text);
filter = false; _event.keyval = 0;
filter = false;
} }
else else
_event.string = g_strdup(_event.string); _event.string = g_strdup(_event.string);
if (!filter) if (!filter)
{ {
//#if DEBUG_IM
//fprintf(stderr, "gKey::enable: gtk_im_context_reset\n"); //fprintf(stderr, "gKey::enable: gtk_im_context_reset\n");
//#endif
//gtk_im_context_reset(_im_context); //gtk_im_context_reset(_im_context);
if (_im_text) 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) 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) if (_im_text)
g_free(_im_text); g_free(_im_text);
@ -188,30 +199,34 @@ void gKey::exit()
void gKey::setActiveControl(gControl *control) void gKey::setActiveControl(gControl *control)
{ {
if (_im_widget) if (_im_control)
{ {
//fprintf(stderr, "gtm_im_context_focus_out\n");
if (!_no_input_method) 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_set_client_window (_im_context, 0);
gtk_im_context_focus_out(_im_context); gtk_im_context_focus_out(_im_context);
} }
_im_widget = NULL; _im_control = NULL;
_no_input_method = false; _no_input_method = false;
} }
if (control) if (control)
{ {
_im_widget = control->widget; _im_control = control;
_no_input_method = control->noInputMethod(); _no_input_method = control->noInputMethod();
if (!_no_input_method) 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_focus_in(_im_context);
gtk_im_context_reset(_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(); control = gDesktop::activeControl();
gKey::enable(widget, &event->key); if (!gKey::enable(control, &event->key))
if (control->onKeyEvent)
{ {
//fprintf(stderr, "gEvent_KeyPress on %p %s\n", control, control->name()); if (gApplication::onKeyEvent)
cancel = control->onKeyEvent(control, gEvent_KeyPress); 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(); gKey::disable();
@ -459,8 +478,8 @@ static void gambas_handle_event(GdkEvent *event)
control = gDesktop::activeControl(); control = gDesktop::activeControl();
gKey::enable(widget, &event->key); if (!gKey::enable(control, &event->key))
control->emit(SIGNAL(control->onKeyEvent), gEvent_KeyRelease); control->emit(SIGNAL(control->onKeyEvent), gEvent_KeyRelease);
gKey::disable(); gKey::disable();
if (event->key.keyval == GDK_Escape) if (event->key.keyval == GDK_Escape)
@ -505,6 +524,7 @@ void *gApplication::_loop_owner = 0;
GtkWindowGroup *gApplication::_group = NULL; GtkWindowGroup *gApplication::_group = NULL;
gControl *gApplication::_enter = NULL; gControl *gApplication::_enter = NULL;
gControl *gApplication::_leave = NULL; gControl *gApplication::_leave = NULL;
bool (*gApplication::onKeyEvent)(int) = NULL;
GtkTooltips* gApplication::tipHandle() GtkTooltips* gApplication::tipHandle()
{ {

View file

@ -63,6 +63,8 @@ public:
static GtkWindowGroup *enterGroup(); static GtkWindowGroup *enterGroup();
static void exitGroup(GtkWindowGroup *oldGroup); static void exitGroup(GtkWindowGroup *oldGroup);
static bool (*onKeyEvent)(int type);
//"Private" //"Private"
static GtkTooltips *tipHandle(); static GtkTooltips *tipHandle();
static bool _busy; static bool _busy;

View file

@ -40,7 +40,7 @@ public:
//"Private" //"Private"
static void disable(); static void disable();
static bool enable(GtkWidget *w, GdkEventKey *e); static bool enable(gControl *control, GdkEventKey *e);
static void init(); static void init();
static void exit(); static void exit();
@ -50,7 +50,7 @@ private:
static GdkEventKey _event; static GdkEventKey _event;
static bool _valid; static bool _valid;
static GtkIMContext *_im_context; static GtkIMContext *_im_context;
static GtkWidget *_im_widget; static gControl *_im_control;
static bool _no_input_method; static bool _no_input_method;
}; };

View file

@ -76,7 +76,6 @@ gTextArea::gTextArea(gContainer *parent) : gControl(parent)
have_cursor = true; have_cursor = true;
use_base = true; use_base = true;
no_input_method = true;
onChange = 0; onChange = 0;
onCursor = 0; onCursor = 0;

View file

@ -56,8 +56,6 @@ gTextBox::gTextBox(gContainer *parent, bool combo) : gControl(parent)
initEntry(); initEntry();
} }
no_input_method = true;
onChange = NULL; onChange = NULL;
onActivate = NULL; onActivate = NULL;
} }

View file

@ -1263,7 +1263,7 @@ void gTree::setSorted(bool v)
return; return;
_sorted = v; _sorted = v;
_sort_column = v ? (view ? 0 : 1) : -1; _sort_column = v ? 0 : -1;
updateSort(); updateSort();
} }

View file

@ -81,12 +81,12 @@ static void my_wait(int duration);
static void my_post(void); static void my_post(void);
static int my_loop(); static int my_loop();
static void my_watch(int fd, int type, void *callback, intptr_t param); static void my_watch(int fd, int type, void *callback, intptr_t param);
bool post_Check=false; static bool post_Check=false;
int MAIN_scale = 8;
static bool _application_keypress = false;
static GB_FUNCTION _application_keypress_func;
int MAIN_scale = 0;
extern "C" 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) static void my_main(int *argc, char **argv)
{ {
gApplication::init(argc, &argv); gApplication::init(argc, &argv);
@ -300,6 +306,12 @@ static void my_main(int *argc, char **argv)
#ifdef GDK_WINDOWING_X11 #ifdef GDK_WINDOWING_X11
X11_init(gdk_x11_display_get_xdisplay(gdk_display_get_default()), gdk_x11_get_default_root_xwindow()); X11_init(gdk_x11_display_get_xdisplay(gdk_display_get_default()), gdk_x11_get_default_root_xwindow());
#endif #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) /*static void raise_timer(GB_TIMER *timer)

View file

@ -313,18 +313,38 @@ MyApplication::MyApplication(int &argc, char **argv)
static bool QT_EventFilter(QEvent *e) static bool QT_EventFilter(QEvent *e)
{ {
QKeyEvent *kevent = (QKeyEvent *)e;
bool cancel; bool cancel;
if (!_application_keypress) if (!_application_keypress)
return false; return false;
CKEY_clear(true); if (e->type() == QEvent::KeyPress)
{
QKeyEvent *kevent = (QKeyEvent *)e;
GB.FreeString(&CKEY_info.text); CKEY_clear(true);
GB.NewString(&CKEY_info.text, QT_ToUTF8(kevent->text()), 0);
CKEY_info.state = kevent->modifiers(); GB.FreeString(&CKEY_info.text);
CKEY_info.code = kevent->key(); 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); GB.Call(&_application_keypress_func, 0, FALSE);
cancel = GB.Stopped(); cancel = GB.Stopped();
@ -346,7 +366,7 @@ bool MyApplication::eventFilter(QObject *o, QEvent *e)
{ {
if (o->isWidgetType()) if (o->isWidgetType())
{ {
if (e->type() == QEvent::KeyPress) if ((e->spontaneous() && e->type() == QEvent::KeyPress) || e->type() == QEvent::InputMethod)
{ {
if (QT_EventFilter(e)) if (QT_EventFilter(e))
return true; return true;