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 }