summaryrefslogtreecommitdiffstats
path: root/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java
diff options
context:
space:
mode:
authorBogdan Gheorghe <gheorghe>2009-07-22 16:44:33 +0000
committerBogdan Gheorghe <gheorghe>2009-07-22 16:44:33 +0000
commit04669c05ebaeea72cc0f94310dd2f03f2fba1e57 (patch)
tree1b8f2af1364f31db65eedf3a6413fb5cb29b7a39 /bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java
parent35438ac71a5f23a7e78a2bb40275c1e8de8e0a81 (diff)
downloadeclipse.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.java112
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);
}