diff options
author | Bogdan Gheorghe <gheorghe> | 2009-07-22 16:44:33 +0000 |
---|---|---|
committer | Bogdan Gheorghe <gheorghe> | 2009-07-22 16:44:33 +0000 |
commit | 04669c05ebaeea72cc0f94310dd2f03f2fba1e57 (patch) | |
tree | 1b8f2af1364f31db65eedf3a6413fb5cb29b7a39 /bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java | |
parent | 35438ac71a5f23a7e78a2bb40275c1e8de8e0a81 (diff) | |
download | eclipse.platform.swt-04669c05ebaeea72cc0f94310dd2f03f2fba1e57.tar.gz eclipse.platform.swt-04669c05ebaeea72cc0f94310dd2f03f2fba1e57.tar.xz eclipse.platform.swt-04669c05ebaeea72cc0f94310dd2f03f2fba1e57.zip |
273850 SWT.MouseDown event not fired on combo widget arrow down (GTK only)
224837 SelectionListener for Combo works incorrectly.
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java')
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java | 112 |
1 files changed, 86 insertions, 26 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java index 6e526d3b05..2b49b0a269 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java @@ -57,13 +57,13 @@ import org.eclipse.swt.events.*; * @noextend This class is not intended to be subclassed by clients. */ public class Combo extends Composite { - int /*long*/ buttonHandle, entryHandle, listHandle, textRenderer, cellHandle, popupHandle; + int /*long*/ buttonHandle, entryHandle, listHandle, textRenderer, cellHandle, popupHandle, menuHandle; int lastEventTime, visibleCount = 5; int /*long*/ gdkEventKey = 0; int fixStart = -1, fixEnd = -1; String [] items = new String [0]; - boolean ignoreSelect, lockText; - + boolean ignoreSelect, lockText, selectionAdded; + int indexSelected; /** * the operating system limit for the number of characters * that the text field in an instance of this class can hold @@ -457,28 +457,16 @@ void createHandle (int index) { display.setWarnings (warnings); OS.gtk_cell_layout_pack_start (handle, textRenderer, true); OS.gtk_cell_layout_set_attributes (handle, textRenderer, OS.text, 0, 0); - - /* - * Feature in GTK. There is no API to query the button - * handle from a combo box although it is possible to get the - * text field. The button handle is needed to hook events. The - * fix is to walk the combo tree and find the first child that is - * an instance of button. + /* + * Feature in GTK. Toggle button creation differs between GTK versions. The + * fix is to call size_request() to force the creation of the button + * for those versions of GTK that defer the creation. */ - OS.gtk_container_forall (handle, display.allChildrenProc, 0); - if (display.allChildren != 0) { - int /*long*/ list = display.allChildren; - while (list != 0) { - int /*long*/ widget = OS.g_list_data (list); - if (OS.GTK_IS_BUTTON (widget)) { - buttonHandle = widget; - break; - } - list = OS.g_list_next (list); - } - OS.g_list_free (display.allChildren); - display.allChildren = 0; + if (OS.GTK_VERSION < OS.VERSION (2, 8, 0)) { + OS.gtk_widget_size_request(handle, new GtkRequisition()); } + if (popupHandle != 0) findMenuHandle (); + findButtonHandle (); /* * Feature in GTK. By default, read only combo boxes * process the RETURN key rather than allowing the @@ -563,6 +551,8 @@ void deregister () { if (buttonHandle != 0) display.removeWidget (buttonHandle); if (entryHandle != 0) display.removeWidget (entryHandle); if (listHandle != 0) display.removeWidget (listHandle); + if (popupHandle != 0) display.removeWidget (popupHandle); + if (menuHandle != 0) display.removeWidget (menuHandle); int /*long*/ imContext = imContext (); if (imContext != 0) display.removeWidget (imContext); } @@ -609,6 +599,48 @@ int /*long*/ findPopupHandle (int /*long*/ oldList) { return hdl; } + +void findButtonHandle() { + /* + * Feature in GTK. There is no API to query the button + * handle from a combo box although it is possible to get the + * text field. The button handle is needed to hook events. The + * fix is to walk the combo tree and find the first child that is + * an instance of button. + */ + OS.gtk_container_forall (handle, display.allChildrenProc, 0); + if (display.allChildren != 0) { + int /*long*/ list = display.allChildren; + while (list != 0) { + int /*long*/ widget = OS.g_list_data (list); + if (OS.GTK_IS_BUTTON (widget)) { + buttonHandle = widget; + break; + } + list = OS.g_list_next (list); + } + OS.g_list_free (display.allChildren); + display.allChildren = 0; + } +} + +void findMenuHandle() { + OS.gtk_container_forall (popupHandle, display.allChildrenProc, 0); + if (display.allChildren != 0) { + int /*long*/ list = display.allChildren; + while (list != 0) { + int /*long*/ widget = OS.g_list_data (list); + if (OS.G_OBJECT_TYPE (widget) == OS.GTK_TYPE_MENU ()) { + menuHandle = widget; + break; + } + list = OS.g_list_next (list); + } + OS.g_list_free (display.allChildren); + display.allChildren = 0; + } +} + void fixModal (int /*long*/ group, int /*long*/ modalGroup) { if (popupHandle != 0) { if (group != 0) { @@ -676,7 +708,7 @@ void hookEvents () { } int eventMask = OS.GDK_POINTER_MOTION_MASK | OS.GDK_BUTTON_PRESS_MASK | OS.GDK_BUTTON_RELEASE_MASK; - int /*long*/ [] handles = new int /*long*/ [] {buttonHandle, entryHandle, listHandle}; + int /*long*/ [] handles = new int /*long*/ [] {buttonHandle, entryHandle, listHandle, menuHandle}; for (int i=0; i<handles.length; i++) { int /*long*/ eventHandle = handles [i]; if (eventHandle != 0) { @@ -709,6 +741,8 @@ void hookEvents () { int blockMask = OS.G_SIGNAL_MATCH_DATA | OS.G_SIGNAL_MATCH_ID; OS.g_signal_handlers_block_matched (imContext, blockMask, id, 0, 0, 0, entryHandle); } + + if (menuHandle != 0) OS.g_signal_connect_closure(menuHandle, OS.selection_done, display.closures[SELECTION_DONE], true); } int /*long*/ imContext () { @@ -1118,7 +1152,7 @@ int /*long*/ gtk_button_press_event (int /*long*/ widget, int /*long*/ event) { if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0)) { GdkEventButton gdkEvent = new GdkEventButton (); OS.memmove (gdkEvent, event, GdkEventButton.sizeof); - if (gdkEvent.type == OS.GDK_BUTTON_PRESS && gdkEvent.button == 1 && (style & SWT.READ_ONLY) != 0) { + if (gdkEvent.type == OS.GDK_BUTTON_PRESS && gdkEvent.button == 1) { return gtk_button_press_event(widget, event, false); } } @@ -1145,6 +1179,7 @@ int /*long*/ gtk_changed (int /*long*/ widget) { */ int index = OS.gtk_combo_box_get_active (handle); if (index != -1) postEvent (SWT.Selection); + indexSelected = -1; return 0; } } else { @@ -1272,10 +1307,23 @@ int /*long*/ gtk_event_after (int /*long*/ widget, int /*long*/ gdkEvent) { OS.memmove (event, gdkEvent, GdkEvent.sizeof); switch (event.type) { case OS.GDK_BUTTON_PRESS: { + if (OS.GTK_VERSION < OS.VERSION (2, 8, 0) && !selectionAdded) { + int /*long*/ grabHandle = OS.gtk_grab_get_current (); + if (grabHandle != 0) { + if (OS.G_OBJECT_TYPE (grabHandle) == OS.GTK_TYPE_MENU ()) { + menuHandle = grabHandle; + OS.g_signal_connect_closure_by_id (menuHandle, display.signalIds [BUTTON_RELEASE_EVENT], 0, display.closures [BUTTON_RELEASE_EVENT], false); + OS.g_signal_connect_closure_by_id (menuHandle, display.signalIds [BUTTON_RELEASE_EVENT], 0, display.closures [BUTTON_RELEASE_EVENT_INVERSE], true); + OS.g_signal_connect_closure (menuHandle, OS.selection_done, display.closures [SELECTION_DONE], false); + display.addWidget (menuHandle, this); + selectionAdded = true; + } + } + } GdkEventButton gdkEventButton = new GdkEventButton (); OS.memmove (gdkEventButton, gdkEvent, GdkEventButton.sizeof); if (gdkEventButton.button == 1) { - if ((style & SWT.READ_ONLY) != 0 && !sendMouseEvent (SWT.MouseDown, gdkEventButton.button, display.clickCount, 0, false, gdkEventButton.time, gdkEventButton.x_root, gdkEventButton.y_root, false, gdkEventButton.state)) { + if (!sendMouseEvent (SWT.MouseDown, gdkEventButton.button, display.clickCount, 0, false, gdkEventButton.time, gdkEventButton.x_root, gdkEventButton.y_root, false, gdkEventButton.state)) { return 1; } if (OS.GTK_VERSION >= OS.VERSION (2, 6, 0)) { @@ -1411,6 +1459,16 @@ int /*long*/ gtk_populate_popup (int /*long*/ widget, int /*long*/ menu) { return 0; } +int /*long*/ gtk_selection_done(int /*long*/ menushell) { + int index = OS.gtk_combo_box_get_active (handle); + if (indexSelected == -1){ + indexSelected = index; + } + else if (index != -1 && indexSelected == index) { + postEvent (SWT.Selection); + } + return 0; +} /** * Searches the receiver's list starting at the first item * (index 0) until an item is found that is equal to the @@ -1511,6 +1569,8 @@ void register () { if (buttonHandle != 0) display.addWidget (buttonHandle, this); if (entryHandle != 0) display.addWidget (entryHandle, this); if (listHandle != 0) display.addWidget (listHandle, this); + if (popupHandle != 0) display.addWidget (popupHandle, this); + if (menuHandle != 0) display.addWidget (menuHandle, this); int /*long*/ imContext = imContext (); if (imContext != 0) display.addWidget (imContext, this); } |