Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/eclipse/swt/widgets/Decorations.java


1   /*******************************************************************************
2    * Copyright (c) 2000, 2004 IBM Corporation and others.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the Common Public License v1.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/cpl-v10.html
7    * 
8    * Contributors:
9    *     IBM Corporation - initial API and implementation
10   *******************************************************************************/
11  package org.eclipse.swt.widgets;
12  
13  import org.eclipse.swt.*;
14  import org.eclipse.swt.internal.gtk.*;
15  import org.eclipse.swt.graphics.*;
16  
17  /**
18   * Instances of this class provide the appearance and
19   * behavior of <code>Shells</code>, but are not top
20   * level shells or dialogs. Class <code>Shell</code>
21   * shares a significant amount of code with this class,
22   * and is a subclass.
23   * <p>
24   * IMPORTANT: This class was intended to be abstract and
25   * should <em>never</em> be referenced or instantiated.
26   * Instead, the class <code>Shell</code> should be used.
27   * </p>
28   * <p>
29   * Instances are always displayed in one of the maximized, 
30   * minimized or normal states:
31   * <ul>
32   * <li>
33   * When an instance is marked as <em>maximized</em>, the
34   * window manager will typically resize it to fill the
35   * entire visible area of the display, and the instance
36   * is usually put in a state where it can not be resized 
37   * (even if it has style <code>RESIZE</code>) until it is
38   * no longer maximized.
39   * </li><li>
40   * When an instance is in the <em>normal</em> state (neither
41   * maximized or minimized), its appearance is controlled by
42   * the style constants which were specified when it was created
43   * and the restrictions of the window manager (see below).
44   * </li><li>
45   * When an instance has been marked as <em>minimized</em>,
46   * its contents (client area) will usually not be visible,
47   * and depending on the window manager, it may be
48   * "iconified" (that is, replaced on the desktop by a small
49   * simplified representation of itself), relocated to a
50   * distinguished area of the screen, or hidden. Combinations
51   * of these changes are also possible.
52   * </li>
53   * </ul>
54   * </p>
55   * Note: The styles supported by this class must be treated
56   * as <em>HINT</em>s, since the window manager for the
57   * desktop on which the instance is visible has ultimate
58   * control over the appearance and behavior of decorations.
59   * For example, some window managers only support resizable
60   * windows and will always assume the RESIZE style, even if
61   * it is not set.
62   * <dl>
63   * <dt><b>Styles:</b></dt>
64   * <dd>BORDER, CLOSE, MIN, MAX, NO_TRIM, RESIZE, TITLE, ON_TOP, TOOL</dd>
65   * <dt><b>Events:</b></dt>
66   * <dd>(none)</dd>
67   * </dl>
68   * Class <code>SWT</code> provides two "convenience constants"
69   * for the most commonly required style combinations:
70   * <dl>
71   * <dt><code>SHELL_TRIM</code></dt>
72   * <dd>
73   * the result of combining the constants which are required
74   * to produce a typical application top level shell: (that 
75   * is, <code>CLOSE | TITLE | MIN | MAX | RESIZE</code>)
76   * </dd>
77   * <dt><code>DIALOG_TRIM</code></dt>
78   * <dd>
79   * the result of combining the constants which are required
80   * to produce a typical application dialog shell: (that 
81   * is, <code>TITLE | CLOSE | BORDER</code>)
82   * </dd>
83   * </dl>
84   * <p>
85   * IMPORTANT: This class is intended to be subclassed <em>only</em>
86   * within the SWT implementation.
87   * </p>
88   *
89   * @see #getMinimized
90   * @see #getMaximized
91   * @see Shell
92   * @see SWT
93   */
94  public class Decorations extends Canvas {
95    String text;
96    Image image;
97    Image [] images = new Image [0];
98    boolean minimized, maximized;
99    Menu menuBar;
100   Menu [] menus;
101   Control savedFocus;
102   Button defaultButton, saveDefault;
103   long /*int*/ accelGroup;  
104   
105 Decorations () {
106   /* Do nothing */
107 }
108 
109 /**
110  * Constructs a new instance of this class given its parent
111  * and a style value describing its behavior and appearance.
112  * <p>
113  * The style value is either one of the style constants defined in
114  * class <code>SWT</code> which is applicable to instances of this
115  * class, or must be built by <em>bitwise OR</em>'ing together 
116  * (that is, using the <code>int</code> "|" operator) two or more
117  * of those <code>SWT</code> style constants. The class description
118  * lists the style constants that are applicable to the class.
119  * Style bits are also inherited from superclasses.
120  * </p>
121  *
122  * @param parent a composite control which will be the parent of the new instance (cannot be null)
123  * @param style the style of control to construct
124  *
125  * @exception IllegalArgumentException <ul>
126  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
127  * </ul>
128  * @exception SWTException <ul>
129  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
130  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
131  * </ul>
132  *
133  * @see SWT#BORDER
134  * @see SWT#CLOSE
135  * @see SWT#MIN
136  * @see SWT#MAX
137  * @see SWT#RESIZE
138  * @see SWT#TITLE
139  * @see SWT#NO_TRIM
140  * @see SWT#SHELL_TRIM
141  * @see SWT#DIALOG_TRIM
142  * @see SWT#ON_TOP
143  * @see SWT#TOOL
144  * @see Widget#checkSubclass
145  * @see Widget#getStyle
146  */
147 public Decorations (Composite parent, int style) {
148   super (parent, checkStyle (style));
149 }
150 
151 static int checkStyle (int style) {
152   if ((style & (SWT.MENU | SWT.MIN | SWT.MAX | SWT.CLOSE)) != 0) {
153     style |= SWT.TITLE;
154   }
155   return style;
156 }
157 
158 void _setImages (Image [] images) {
159   long /*int*/ pixbufs = 0;
160   if (images != null) {
161     for (int i = 0; i < images.length; i++) {
162       Image icon = images [i];
163       int [] w = new int [1], h = new int [1];
164       OS.gdk_drawable_get_size (icon.pixmap, w, h);
165       int width = w [0], height = h [0];   
166       boolean hasMask = icon.mask != 0;
167       long /*int*/ pixbuf = OS.gdk_pixbuf_new (OS.GDK_COLORSPACE_RGB, hasMask, 8, width, height);
168       if (pixbuf == 0) SWT.error (SWT.ERROR_NO_HANDLES);
169       long /*int*/ colormap = OS.gdk_colormap_get_system ();
170       OS.gdk_pixbuf_get_from_drawable (pixbuf, icon.pixmap, colormap, 0, 0, 0, 0, width, height);
171       if (hasMask) {
172         long /*int*/ gdkMaskImagePtr = OS.gdk_drawable_get_image (icon.mask, 0, 0, width, height);
173         if (gdkMaskImagePtr == 0) SWT.error (SWT.ERROR_NO_HANDLES);
174         int stride = OS.gdk_pixbuf_get_rowstride (pixbuf);
175         long /*int*/ pixels = OS.gdk_pixbuf_get_pixels (pixbuf);
176         byte [] line = new byte [stride];
177         for (int y=0; y<height; y++) {
178           long /*int*/ offset = pixels + (y * stride);
179           OS.memmove (line, offset, stride);
180           for (int x=0; x<width; x++) {
181             if (OS.gdk_image_get_pixel (gdkMaskImagePtr, x, y) == 0) {
182               line[x*4+3] = 0;
183             }
184           }
185           OS.memmove (offset, line, stride);
186         }
187         OS.g_object_unref (gdkMaskImagePtr);
188       }
189       pixbufs = OS.g_list_append (pixbufs, pixbuf);      
190     }
191   }
192   long /*int*/ window = OS.GTK_WIDGET_WINDOW (topHandle ());
193   OS.gdk_window_set_icon_list (window, pixbufs);
194   long /*int*/ [] data = new long /*int*/ [1];
195   long /*int*/ temp = pixbufs;
196   while (temp != 0) {
197     OS.memmove (data, temp, OS.PTR_SIZEOF);
198     OS.g_object_unref (data [0]);
199     temp = OS.g_list_next (temp);
200   }
201   if (pixbufs != 0) OS.g_list_free (pixbufs);
202 }
203 
204 void add (Menu menu) {
205   if (menus == null) menus = new Menu [4];
206   for (int i=0; i<menus.length; i++) {
207     if (menus [i] == null) {
208       menus [i] = menu;
209       return;
210     }
211   }
212   Menu [] newMenus = new Menu [menus.length + 4];
213   newMenus [menus.length] = menu;
214   System.arraycopy (menus, 0, newMenus, 0, menus.length);
215   menus = newMenus;
216 }
217 
218 Control computeTabGroup () {
219   return this;
220 }
221 
222 Control computeTabRoot () {
223   return this;
224 }
225 
226 void createAccelGroup () {
227   if (accelGroup != 0) return;
228   accelGroup = OS.gtk_accel_group_new ();
229   if (accelGroup == 0) SWT.error (SWT.ERROR_NO_HANDLES);
230   //FIXME - what should we do for Decorations
231   long /*int*/ shellHandle = topHandle ();
232   OS.gtk_window_add_accel_group (shellHandle, accelGroup);
233 }
234 
235 void createWidget (int index) {
236   super.createWidget (index);
237   text = "";
238 }
239 
240 void destroyAccelGroup () {
241   if (accelGroup == 0) return;
242   long /*int*/ shellHandle = topHandle ();
243   OS.gtk_window_remove_accel_group (shellHandle, accelGroup);
244   //TEMPORARY CODE
245 //  OS.g_object_unref (accelGroup);
246   accelGroup = 0;
247 }
248 
249 void fixAccelGroup () {
250   if (menuBar == null) return;
251   destroyAccelGroup ();
252   createAccelGroup ();
253   menuBar.addAccelerators (accelGroup);
254 }
255 
256 void fixDecorations (Decorations newDecorations, Control control, Menu [] menus) {
257   if (this == newDecorations) return;
258   if (control == savedFocus) savedFocus = null;
259   if (control == defaultButton) defaultButton = null;
260   if (control == saveDefault) saveDefault = null;
261   if (menus == null) return;
262   Menu menu = control.menu;
263   if (menu != null) {
264     int index = 0;
265     while (index <menus.length) {
266       if (menus [index] == menu) {
267         control.setMenu (null);
268         return;
269       }
270       index++;
271     }
272     menu.fixMenus (newDecorations);
273   }
274 }
275 
276 /**
277  * Returns the receiver's default button if one had
278  * previously been set, otherwise returns null.
279  *
280  * @return the default button or null
281  *
282  * @exception SWTException <ul>
283  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
284  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
285  * </ul>
286  *
287  * @see #setDefaultButton
288  */
289 public Button getDefaultButton () {
290   checkWidget();
291   return defaultButton != null ? defaultButton : saveDefault;
292 }
293 
294 /**
295  * Returns the receiver's image if it had previously been 
296  * set using <code>setImage()</code>. The image is typically
297  * displayed by the window manager when the instance is
298  * marked as iconified, and may also be displayed somewhere
299  * in the trim when the instance is in normal or maximized
300  * states.
301  * <p>
302  * Note: This method will return null if called before
303  * <code>setImage()</code> is called. It does not provide
304  * access to a window manager provided, "default" image
305  * even if one exists.
306  * </p>
307  * 
308  * @return the image
309  *
310  * @exception SWTException <ul>
311  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
312  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
313  * </ul>
314  */
315 public Image getImage () {
316   checkWidget ();
317   return image;
318 }
319 
320 /**
321  * Returns the receiver's images if they had previously been 
322  * set using <code>setImages()</code>. Images are typically
323  * displayed by the window manager when the instance is
324  * marked as iconified, and may also be displayed somewhere
325  * in the trim when the instance is in normal or maximized
326  * states. Depending where the icon is displayed, the platform
327  * chooses the icon with the "best" size. It is expected that
328  * the array will contain the same icon rendered at different
329  * resolutions.
330  * 
331  * <p>
332  * Note: This method will return an empty array if called before
333  * <code>setImages()</code> is called. It does not provide
334  * access to a window manager provided, "default" image
335  * even if one exists.
336  * </p>
337  * 
338  * @return the images
339  *
340  * @exception SWTException <ul>
341  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
342  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
343  * </ul>
344  * 
345  * @since 3.0
346  */
347 public Image [] getImages () {
348   checkWidget ();
349   return images;
350 }
351 
352 /**
353  * Returns <code>true</code> if the receiver is currently
354  * maximized, and false otherwise. 
355  * <p>
356  *
357  * @return the maximized state
358  *
359  * @exception SWTException <ul>
360  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
361  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
362  * </ul>
363  *
364  * @see #setMaximized
365  */
366 public boolean getMaximized () {
367   checkWidget();
368   return maximized;
369 }
370 
371 /**
372  * Returns the receiver's menu bar if one had previously
373  * been set, otherwise returns null.
374  *
375  * @return the menu bar or null
376  *
377  * @exception SWTException <ul>
378  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
379  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
380  * </ul>
381  */
382 public Menu getMenuBar () {
383   checkWidget();
384   return menuBar;
385 }
386 
387 /**
388  * Returns <code>true</code> if the receiver is currently
389  * minimized, and false otherwise. 
390  * <p>
391  *
392  * @return the minimized state
393  *
394  * @exception SWTException <ul>
395  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
396  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
397  * </ul>
398  *
399  * @see #setMinimized
400  */
401 public boolean getMinimized () {
402   checkWidget();
403   return minimized;
404 }
405 
406 String getNameText () {
407   return getText ();
408 }
409 
410 /**
411  * Returns the receiver's text, which is the string that the
412  * window manager will typically display as the receiver's
413  * <em>title</em>. If the text has not previously been set, 
414  * returns an empty string.
415  *
416  * @return the text
417  *
418  * @exception SWTException <ul>
419  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
420  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
421  * </ul>
422  */
423 public String getText () {
424   checkWidget();
425   return text;
426 }
427 
428 public boolean isReparentable () {
429   checkWidget ();
430   return false;
431 }
432 
433 boolean isTabGroup () {
434   return true;
435 }
436 
437 boolean isTabItem () {
438   return false;
439 }
440 
441 Decorations menuShell () {
442   return this;
443 }
444 
445 void remove (Menu menu) {
446   if (menus == null) return;
447   for (int i=0; i<menus.length; i++) {
448     if (menus [i] == menu) {
449       menus [i] = null;
450       return;
451     }
452   }
453 }
454 
455 void releaseWidget () {
456   if (menuBar != null) menuBar.releaseResources ();
457   menuBar = null;
458   if (menus != null) {
459     for (int i=0; i<menus.length; i++) {
460       Menu menu = menus [i];
461       if (menu != null && !menu.isDisposed ()) {
462         menu.dispose ();
463       }
464     }
465   }
466   menus = null;
467   super.releaseWidget ();
468   image = null;
469   images = null;
470   savedFocus = null;
471   defaultButton = saveDefault = null;
472 }
473 
474 boolean restoreFocus () {
475   if (savedFocus != null && savedFocus.isDisposed ()) savedFocus = null;
476   boolean restored = savedFocus != null && savedFocus.setFocus ();
477   savedFocus = null;
478   /*
479   * This code is intentionally commented.  When no widget
480   * has been given focus, some platforms give focus to the
481   * default button.  Motif doesn't do this.
482   */
483 //  if (restored) return true;
484 //  if (defaultButton != null && !defaultButton.isDisposed ()) {
485 //    if (defaultButton.setFocus ()) return true;
486 //  }
487 //  return false;
488   return restored;
489 }
490 
491 /**
492  * If the argument is not null, sets the receiver's default
493  * button to the argument, and if the argument is null, sets
494  * the receiver's default button to the first button which
495  * was set as the receiver's default button (called the 
496  * <em>saved default button</em>). If no default button had
497  * previously been set, or the saved default button was
498  * disposed, the receiver's default button will be set to
499  * null. 
500  *
501  * @param button the new default button
502  *
503  * @exception IllegalArgumentException <ul>
504  *    <li>ERROR_INVALID_ARGUMENT - if the button has been disposed</li> 
505  * </ul>
506  * @exception SWTException <ul>
507  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
508  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
509  * </ul>
510  */
511 public void setDefaultButton (Button button) {
512   checkWidget();
513   long /*int*/ buttonHandle = 0;
514   if (button != null) {
515     if (button.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
516     buttonHandle = button.handle;
517   }
518   saveDefault = defaultButton = button;
519   OS.gtk_window_set_default (topHandle (), buttonHandle);
520 }
521 
522 /**
523  * Sets the receiver's image to the argument, which may
524  * be null. The image is typically displayed by the window
525  * manager when the instance is marked as iconified, and
526  * may also be displayed somewhere in the trim when the
527  * instance is in normal or maximized states.
528  * 
529  * @param image the new image (or null)
530  *
531  * @exception IllegalArgumentException <ul>
532  *    <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li> 
533  * </ul>
534  * @exception SWTException <ul>
535  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
536  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
537  * </ul>
538  */
539 public void setImage (Image image) {
540   checkWidget ();
541   this.image = image;
542   _setImages (image != null ? new Image [] {image} : null);
543 }
544 
545 /**
546  * Sets the receiver's images to the argument, which may
547  * be an empty array. Images are typically displayed by the
548  * window manager when the instance is marked as iconified,
549  * and may also be displayed somewhere in the trim when the
550  * instance is in normal or maximized states. Depending where
551  * the icon is displayed, the platform chooses the icon with
552  * the "best" size. It is expected that the array will contain
553  * the same icon rendered at different resolutions.
554  * 
555  * @param images the new image array
556  *
557  * @exception IllegalArgumentException <ul>
558  *    <li>ERROR_NULL_ARGUMENT - if the array of images is null</li>
559  *    <li>ERROR_INVALID_ARGUMENT - if one of the images has been disposed</li>
560  * </ul>
561  * @exception SWTException <ul>
562  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
563  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
564  * </ul>
565  * 
566  * @since 3.0
567  */
568 public void setImages (Image [] images) {
569   checkWidget ();
570   if (images == null) error (SWT.ERROR_INVALID_ARGUMENT);
571   for (int i = 0; i < images.length; i++) {
572     if (images [i] == null || images [i].isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
573   }
574   this.images = images;
575   _setImages (images);
576 }
577 
578 /**
579  * Sets the maximized state of the receiver.
580  * If the argument is <code>true</code> causes the receiver
581  * to switch to the maximized state, and if the argument is
582  * <code>false</code> and the receiver was previously maximized,
583  * causes the receiver to switch back to either the minimized
584  * or normal states.
585  * <p>
586  * Note: The result of intermixing calls to<code>setMaximized(true)</code>
587  * and <code>setMinimized(true)</code> will vary by platform. Typically,
588  * the behavior will match the platform user's expectations, but not
589  * always. This should be avoided if possible.
590  * </p>
591  *
592  * @param maximized the new maximized state
593  *
594  * @exception SWTException <ul>
595  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
596  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
597  * </ul>
598  *
599  * @see #setMinimized
600  */
601 public void setMaximized (boolean maximized) {
602   checkWidget();
603   this.maximized = maximized;
604 }
605 
606 /**
607  * Sets the receiver's menu bar to the argument, which
608  * may be null.
609  *
610  * @param menu the new menu bar
611  *
612  * @exception IllegalArgumentException <ul>
613  *    <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li> 
614  *    <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li>
615  * </ul>
616  * @exception SWTException <ul>
617  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
618  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
619  * </ul>
620  */
621 public void setMenuBar (Menu menu) {
622   checkWidget();
623   if (menuBar == menu) return;
624   if (menu != null) {
625     if ((menu.style & SWT.BAR) == 0) error (SWT.ERROR_MENU_NOT_BAR);
626     if (menu.parent != this) error (SWT.ERROR_INVALID_PARENT);
627   }
628   menuBar = menu;
629 }
630 
631 /**
632  * Sets the minimized stated of the receiver.
633  * If the argument is <code>true</code> causes the receiver
634  * to switch to the minimized state, and if the argument is
635  * <code>false</code> and the receiver was previously minimized,
636  * causes the receiver to switch back to either the maximized
637  * or normal states.
638  * <p>
639  * Note: The result of intermixing calls to<code>setMaximized(true)</code>
640  * and <code>setMinimized(true)</code> will vary by platform. Typically,
641  * the behavior will match the platform user's expectations, but not
642  * always. This should be avoided if possible.
643  * </p>
644  *
645  * @param minimized the new maximized state
646  *
647  * @exception SWTException <ul>
648  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
649  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
650  * </ul>
651  *
652  * @see #setMaximized
653  */
654 public void setMinimized (boolean minimized) {
655   checkWidget();
656   this.minimized = minimized;
657 }
658 
659 void setSavedFocus (Control control) {
660   if (this == control) return;
661   savedFocus = control;
662 }
663 
664 /**
665  * Sets the receiver's text, which is the string that the
666  * window manager will typically display as the receiver's
667  * <em>title</em>, to the argument, which may not be null. 
668  *
669  * @param string the new text
670  *
671  * @exception IllegalArgumentException <ul>
672  *    <li>ERROR_NULL_ARGUMENT - if the text is null</li>
673  * </ul>
674  * @exception SWTException <ul>
675  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
676  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
677  * </ul>
678  */
679 public void setText (String string) {
680   checkWidget();
681   if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
682   text = string;
683 }
684 
685 boolean traverseItem (boolean next) {
686   return false;
687 }
688 
689 boolean traverseReturn () {
690   Button button = defaultButton != null ? defaultButton: saveDefault;
691   if (button == null || button.isDisposed ()) return false;
692   /*
693   * Bug in GTK.  When a default button that is disabled is
694   * activated using the Enter key, GTK GP's.  The fix is to
695   * detect this case and stop GTK from processing the Enter
696   * key.
697   */
698   if (!button.isVisible () || !button.isEnabled ()) return true;
699   long /*int*/ shellHandle = _getShell ().topHandle ();
700   return OS.gtk_window_activate_default (shellHandle);
701 }
702 
703 }