* 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 "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);
}
//fprintf(stderr, "gtm_im_context_focus_in\n");
#if DEBUG_IM
fprintf(stderr, "gtm_im_context_focus_in\n");
#endif
}
}
}
@ -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()
{

View file

@ -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;

View file

@ -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;
};

View file

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

View file

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

View file

@ -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();
}

View file

@ -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)

View file

@ -313,24 +313,44 @@ 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;
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();
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();
CKEY_clear(false);
return cancel;
}
@ -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;