1 /* winmenu.c - command menu for windows
3 * Window Maker window manager
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <X11/Xutil.h>
31 #include <X11/XKBlib.h>
33 #include "WindowMaker.h"
39 #include "application.h"
43 #include "workspace.h"
44 #include "winspector.h"
91 static void updateOptionsMenu(WMenu
* menu
, WWindow
* wwin
);
93 static void execWindowOptionCommand(WMenu
* menu
, WMenuEntry
* entry
)
95 WWindow
*wwin
= (WWindow
*) entry
->clientdata
;
97 /* Parameter not used, but tell the compiler that it is ok */
100 switch (entry
->order
) {
102 if (wwin
->frame
->core
->stacking
->window_level
!= WMFloatingLevel
)
103 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
105 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
108 case WO_KEEP_AT_BOTTOM
:
109 if (wwin
->frame
->core
->stacking
->window_level
!= WMSunkenLevel
)
110 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
112 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
116 wWindowSetOmnipresent(wwin
, !wwin
->flags
.omnipresent
);
121 static void execMaximizeCommand(WMenu
* menu
, WMenuEntry
* entry
)
123 WWindow
*wwin
= (WWindow
*) entry
->clientdata
;
128 switch (entry
->order
) {
130 handleMaximize(wwin
, MAX_VERTICAL
);
134 handleMaximize(wwin
,MAX_HORIZONTAL
);
138 handleMaximize(wwin
,MAX_VERTICAL
| MAX_LEFTHALF
);
142 handleMaximize(wwin
,MAX_VERTICAL
| MAX_RIGHTHALF
);
146 handleMaximize(wwin
,MAX_HORIZONTAL
| MAX_TOPHALF
);
150 handleMaximize(wwin
,MAX_HORIZONTAL
| MAX_BOTTOMHALF
);
154 handleMaximize(wwin
,MAX_LEFTHALF
| MAX_TOPHALF
);
158 handleMaximize(wwin
,MAX_RIGHTHALF
| MAX_TOPHALF
);
162 handleMaximize(wwin
,MAX_LEFTHALF
| MAX_BOTTOMHALF
);
166 handleMaximize(wwin
,MAX_RIGHTHALF
| MAX_BOTTOMHALF
);
170 handleMaximize(wwin
,MAX_MAXIMUS
);
176 static void updateUnmaximizeShortcut(WMenuEntry
* entry
, int flags
)
180 switch (flags
& (MAX_HORIZONTAL
| MAX_VERTICAL
| MAX_LEFTHALF
| MAX_RIGHTHALF
| MAX_TOPHALF
| MAX_BOTTOMHALF
| MAX_MAXIMUS
)) {
182 key
= WKBD_HMAXIMIZE
;
186 key
= WKBD_VMAXIMIZE
;
189 case MAX_LEFTHALF
| MAX_VERTICAL
:
190 key
= WKBD_LHMAXIMIZE
;
193 case MAX_RIGHTHALF
| MAX_VERTICAL
:
194 key
= WKBD_RHMAXIMIZE
;
197 case MAX_TOPHALF
| MAX_HORIZONTAL
:
198 key
= WKBD_THMAXIMIZE
;
201 case MAX_BOTTOMHALF
| MAX_HORIZONTAL
:
202 key
= WKBD_BHMAXIMIZE
;
205 case MAX_LEFTHALF
| MAX_TOPHALF
:
206 key
= WKBD_LTCMAXIMIZE
;
209 case MAX_RIGHTHALF
| MAX_TOPHALF
:
210 key
= WKBD_RTCMAXIMIZE
;
213 case MAX_LEFTHALF
| MAX_BOTTOMHALF
:
214 key
= WKBD_LBCMAXIMIZE
;
217 case MAX_RIGHTHALF
| MAX_BOTTOMHALF
:
218 key
= WKBD_RBCMAXIMIZE
;
230 entry
->rtext
= GetShortcutKey(wKeyBindings
[key
]);
233 static void execMenuCommand(WMenu
* menu
, WMenuEntry
* entry
)
235 WWindow
*wwin
= (WWindow
*) entry
->clientdata
;
238 CloseWindowMenu(menu
->frame
->screen_ptr
);
240 switch (entry
->order
) {
242 /* send delete message */
243 wClientSendProtocol(wwin
, w_global
.atom
.wm
.delete_window
,
244 w_global
.timestamp
.last_event
);
249 if (wPreferences
.dont_confirm_kill
250 || wMessageDialog(menu
->frame
->screen_ptr
, _("Kill Application"),
252 ("This will kill the application.\nAny unsaved changes will be lost.\nPlease confirm."),
253 _("Yes"), _("No"), NULL
) == WAPRDefault
) {
254 if (!wwin
->flags
.destroyed
)
261 if (wwin
->flags
.miniaturized
) {
262 wDeiconifyWindow(wwin
);
264 if (wwin
->protocols
.MINIATURIZE_WINDOW
) {
265 wClientSendProtocol(wwin
, w_global
.atom
.gnustep
.wm_miniaturize_window
,
266 w_global
.timestamp
.last_event
);
268 wIconifyWindow(wwin
);
274 if (wwin
->flags
.maximized
)
275 wUnmaximizeWindow(wwin
);
277 wMaximizeWindow(wwin
, MAX_VERTICAL
| MAX_HORIZONTAL
);
281 if (wwin
->flags
.shaded
)
282 wUnshadeWindow(wwin
);
288 if (!wwin
->flags
.miniaturized
)
289 wSelectWindow(wwin
, !wwin
->flags
.selected
);
291 wIconSelect(wwin
->icon
);
295 wKeyboardMoveResizeWindow(wwin
);
299 wShowInspectorForWindow(wwin
);
303 (void) RelaunchWindow(wwin
);
307 wapp
= wApplicationOf(wwin
->main_window
);
308 wHideApplication(wapp
);
313 static void switchWSCommand(WMenu
* menu
, WMenuEntry
* entry
)
315 WWindow
*wwin
= (WWindow
*) entry
->clientdata
;
317 /* Parameter not used, but tell the compiler that it is ok */
320 wSelectWindow(wwin
, False
);
321 wWindowChangeWorkspace(wwin
, entry
->order
);
324 static void makeShortcutCommand(WMenu
*menu
, WMenuEntry
*entry
)
326 WWindow
*wwin
= (WWindow
*) entry
->clientdata
;
327 WScreen
*scr
= wwin
->screen_ptr
;
328 int index
= entry
->order
- WO_ENTRIES
;
330 /* Parameter not used, but tell the compiler that it is ok */
333 if (w_global
.shortcut
.windows
[index
]) {
334 WMFreeArray(w_global
.shortcut
.windows
[index
]);
335 w_global
.shortcut
.windows
[index
] = NULL
;
338 if (wwin
->flags
.selected
&& scr
->selected_windows
) {
339 w_global
.shortcut
.windows
[index
] = WMDuplicateArray(scr
->selected_windows
);
341 w_global
.shortcut
.windows
[index
] = WMCreateArray(4);
342 WMAddToArray(w_global
.shortcut
.windows
[index
], wwin
);
345 wSelectWindow(wwin
, !wwin
->flags
.selected
);
348 wSelectWindow(wwin
, !wwin
->flags
.selected
);
352 static void updateWorkspaceMenu(WMenu
* menu
)
354 char title
[MAX_WORKSPACENAME_WIDTH
+ 1];
358 for (i
= 0; i
< w_global
.workspace
.count
; i
++) {
359 if (i
< menu
->entry_no
) {
361 entry
= menu
->entries
[i
];
362 if (strcmp(entry
->text
, w_global
.workspace
.array
[i
]->name
) != 0) {
364 strncpy(title
, w_global
.workspace
.array
[i
]->name
, MAX_WORKSPACENAME_WIDTH
);
365 title
[MAX_WORKSPACENAME_WIDTH
] = 0;
366 menu
->entries
[i
]->text
= wstrdup(title
);
367 menu
->entries
[i
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_MOVE_WORKSPACE1
+ i
]);
368 menu
->flags
.realized
= 0;
371 strncpy(title
, w_global
.workspace
.array
[i
]->name
, MAX_WORKSPACENAME_WIDTH
);
372 title
[MAX_WORKSPACENAME_WIDTH
] = 0;
374 entry
= wMenuAddCallback(menu
, title
, switchWSCommand
, NULL
);
375 entry
->rtext
= GetShortcutKey(wKeyBindings
[WKBD_MOVE_WORKSPACE1
+ i
]);
377 menu
->flags
.realized
= 0;
380 /* workspace shortcut labels */
381 if (i
/ 10 == w_global
.workspace
.current
/ 10)
382 entry
->rtext
= GetShortcutKey(wKeyBindings
[WKBD_MOVE_WORKSPACE1
+ (i
% 10)]);
387 if (!menu
->flags
.realized
)
391 static void updateMakeShortcutMenu(WMenu
*menu
, WWindow
*wwin
)
393 WMenu
*smenu
= menu
->cascades
[menu
->entries
[MC_OPTIONS
]->cascade
];
402 buflen
= strlen(_("Set Shortcut")) + 16;
403 buffer
= wmalloc(buflen
);
405 for (i
= WO_ENTRIES
; i
< smenu
->entry_no
; i
++) {
407 int shortcutNo
= i
- WO_ENTRIES
;
408 WMenuEntry
*entry
= smenu
->entries
[i
];
409 WMArray
*shortSelWindows
= w_global
.shortcut
.windows
[shortcutNo
];
411 snprintf(buffer
, buflen
, "%s %i", _("Set Shortcut"), shortcutNo
+ 1);
413 if (!shortSelWindows
) {
414 entry
->flags
.indicator_on
= 0;
416 entry
->flags
.indicator_on
= 1;
417 if (WMCountInArray(shortSelWindows
, wwin
))
418 entry
->flags
.indicator_type
= MI_DIAMOND
;
420 entry
->flags
.indicator_type
= MI_CHECK
;
423 if (strcmp(buffer
, entry
->text
) != 0) {
425 entry
->text
= wstrdup(buffer
);
426 smenu
->flags
.realized
= 0;
429 kcode
= wKeyBindings
[WKBD_WINDOW1
+ shortcutNo
].keycode
;
432 if ((tmp
= GetShortcutKey(wKeyBindings
[WKBD_WINDOW1
+ shortcutNo
]))
433 && (!entry
->rtext
|| strcmp(tmp
, entry
->rtext
) != 0)) {
437 smenu
->flags
.realized
= 0;
439 wMenuSetEnabled(smenu
, i
, True
);
441 wMenuSetEnabled(smenu
, i
, False
);
445 smenu
->flags
.realized
= 0;
448 entry
->clientdata
= wwin
;
451 if (!smenu
->flags
.realized
)
455 static void updateOptionsMenu(WMenu
* menu
, WWindow
* wwin
)
457 WMenu
*smenu
= menu
->cascades
[menu
->entries
[MC_OPTIONS
]->cascade
];
459 /* keep on top check */
460 smenu
->entries
[WO_KEEP_ON_TOP
]->clientdata
= wwin
;
461 smenu
->entries
[WO_KEEP_ON_TOP
]->flags
.indicator_on
=
462 (wwin
->frame
->core
->stacking
->window_level
== WMFloatingLevel
) ? 1 : 0;
463 wMenuSetEnabled(smenu
, WO_KEEP_ON_TOP
, !wwin
->flags
.miniaturized
);
465 /* keep at bottom check */
466 smenu
->entries
[WO_KEEP_AT_BOTTOM
]->clientdata
= wwin
;
467 smenu
->entries
[WO_KEEP_AT_BOTTOM
]->flags
.indicator_on
=
468 (wwin
->frame
->core
->stacking
->window_level
== WMSunkenLevel
) ? 1 : 0;
469 wMenuSetEnabled(smenu
, WO_KEEP_AT_BOTTOM
, !wwin
->flags
.miniaturized
);
471 /* omnipresent check */
472 smenu
->entries
[WO_OMNIPRESENT
]->clientdata
= wwin
;
473 smenu
->entries
[WO_OMNIPRESENT
]->flags
.indicator_on
= IS_OMNIPRESENT(wwin
);
475 smenu
->flags
.realized
= 0;
479 static void updateMaximizeMenu(WMenu
* menu
, WWindow
* wwin
)
481 WMenu
*smenu
= menu
->cascades
[menu
->entries
[MC_OTHERMAX
]->cascade
];
483 smenu
->entries
[MAXC_V
]->clientdata
= wwin
;
484 smenu
->entries
[MAXC_V
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_VMAXIMIZE
]);
486 smenu
->entries
[MAXC_H
]->clientdata
= wwin
;
487 smenu
->entries
[MAXC_H
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_HMAXIMIZE
]);
489 smenu
->entries
[MAXC_LH
]->clientdata
= wwin
;
490 smenu
->entries
[MAXC_LH
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_LHMAXIMIZE
]);
492 smenu
->entries
[MAXC_RH
]->clientdata
= wwin
;
493 smenu
->entries
[MAXC_RH
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_RHMAXIMIZE
]);
495 smenu
->entries
[MAXC_TH
]->clientdata
= wwin
;
496 smenu
->entries
[MAXC_TH
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_THMAXIMIZE
]);
498 smenu
->entries
[MAXC_BH
]->clientdata
= wwin
;
499 smenu
->entries
[MAXC_BH
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_BHMAXIMIZE
]);
501 smenu
->entries
[MAXC_LTC
]->clientdata
= wwin
;
502 smenu
->entries
[MAXC_LTC
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_LTCMAXIMIZE
]);
504 smenu
->entries
[MAXC_RTC
]->clientdata
= wwin
;
505 smenu
->entries
[MAXC_RTC
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_RTCMAXIMIZE
]);
507 smenu
->entries
[MAXC_LBC
]->clientdata
= wwin
;
508 smenu
->entries
[MAXC_LBC
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_LBCMAXIMIZE
]);
510 smenu
->entries
[MAXC_RBC
]->clientdata
= wwin
;
511 smenu
->entries
[MAXC_RBC
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_RBCMAXIMIZE
]);
513 smenu
->entries
[MAXC_MAXIMUS
]->clientdata
= wwin
;
514 smenu
->entries
[MAXC_MAXIMUS
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_MAXIMUS
]);
516 smenu
->flags
.realized
= 0;
520 static WMenu
*makeWorkspaceMenu(WScreen
* scr
)
524 menu
= wMenuCreate(scr
, NULL
, False
);
526 wwarning(_("could not create submenu for window menu"));
530 updateWorkspaceMenu(menu
);
535 static WMenu
*makeMakeShortcutMenu(WMenu
*menu
)
539 for (i
= 0; i
< MAX_WINDOW_SHORTCUTS
; i
++) {
541 entry
= wMenuAddCallback(menu
, "", makeShortcutCommand
, NULL
);
543 entry
->flags
.indicator
= 1;
549 static WMenu
*makeOptionsMenu(WScreen
* scr
)
554 menu
= wMenuCreate(scr
, NULL
, False
);
556 wwarning(_("could not create submenu for window menu"));
560 entry
= wMenuAddCallback(menu
, _("Keep on top"), execWindowOptionCommand
, NULL
);
561 entry
->flags
.indicator
= 1;
562 entry
->flags
.indicator_type
= MI_CHECK
;
564 entry
= wMenuAddCallback(menu
, _("Keep at bottom"), execWindowOptionCommand
, NULL
);
565 entry
->flags
.indicator
= 1;
566 entry
->flags
.indicator_type
= MI_CHECK
;
568 entry
= wMenuAddCallback(menu
, _("Omnipresent"), execWindowOptionCommand
, NULL
);
569 entry
->flags
.indicator
= 1;
570 entry
->flags
.indicator_type
= MI_CHECK
;
575 static WMenu
*makeMaximizeMenu(WScreen
* scr
)
579 menu
= wMenuCreate(scr
, NULL
, False
);
581 wwarning(_("could not create submenu for window menu"));
585 (void) wMenuAddCallback(menu
, _("Maximize vertically"), execMaximizeCommand
, NULL
);
586 (void) wMenuAddCallback(menu
, _("Maximize horizontally"), execMaximizeCommand
, NULL
);
587 (void) wMenuAddCallback(menu
, _("Maximize left half"), execMaximizeCommand
, NULL
);
588 (void) wMenuAddCallback(menu
, _("Maximize right half"), execMaximizeCommand
, NULL
);
589 (void) wMenuAddCallback(menu
, _("Maximize top half"), execMaximizeCommand
, NULL
);
590 (void) wMenuAddCallback(menu
, _("Maximize bottom half"), execMaximizeCommand
, NULL
);
591 (void) wMenuAddCallback(menu
, _("Maximize left top corner"), execMaximizeCommand
, NULL
);
592 (void) wMenuAddCallback(menu
, _("Maximize right top corner"), execMaximizeCommand
, NULL
);
593 (void) wMenuAddCallback(menu
, _("Maximize left bottom corner"), execMaximizeCommand
, NULL
);
594 (void) wMenuAddCallback(menu
, _("Maximize right bottom corner"), execMaximizeCommand
, NULL
);
595 (void) wMenuAddCallback(menu
, _("Maximus: tiled maximization"), execMaximizeCommand
, NULL
);
600 static WMenu
*createWindowMenu(WScreen
* scr
)
605 menu
= wMenuCreate(scr
, NULL
, False
);
607 * Warning: If you make some change that affects the order of the
608 * entries, you must update the command enum in the top of
611 entry
= wMenuAddCallback(menu
, _("Maximize"), execMenuCommand
, NULL
);
613 entry
= wMenuAddCallback(menu
, _("Other maximization"), NULL
, NULL
);
614 wMenuEntrySetCascade(menu
, entry
, makeMaximizeMenu(scr
));
616 entry
= wMenuAddCallback(menu
, _("Miniaturize"), execMenuCommand
, NULL
);
618 entry
= wMenuAddCallback(menu
, _("Shade"), execMenuCommand
, NULL
);
620 entry
= wMenuAddCallback(menu
, _("Hide"), execMenuCommand
, NULL
);
622 entry
= wMenuAddCallback(menu
, _("Resize/Move"), execMenuCommand
, NULL
);
624 entry
= wMenuAddCallback(menu
, _("Select"), execMenuCommand
, NULL
);
626 entry
= wMenuAddCallback(menu
, _("Move To"), NULL
, NULL
);
627 w_global
.workspace
.submenu
= makeWorkspaceMenu(scr
);
628 if (w_global
.workspace
.submenu
)
629 wMenuEntrySetCascade(menu
, entry
, w_global
.workspace
.submenu
);
631 entry
= wMenuAddCallback(menu
, _("Attributes..."), execMenuCommand
, NULL
);
633 entry
= wMenuAddCallback(menu
, _("Options"), NULL
, NULL
);
634 wMenuEntrySetCascade(menu
, entry
, makeMakeShortcutMenu(makeOptionsMenu(scr
)));
636 entry
= wMenuAddCallback(menu
, _("Launch"), execMenuCommand
, NULL
);
638 entry
= wMenuAddCallback(menu
, _("Close"), execMenuCommand
, NULL
);
640 entry
= wMenuAddCallback(menu
, _("Kill"), execMenuCommand
, NULL
);
645 void CloseWindowMenu(WScreen
* scr
)
647 if (scr
->window_menu
) {
648 if (scr
->window_menu
->flags
.mapped
)
649 wMenuUnmap(scr
->window_menu
);
651 if (scr
->window_menu
->entries
[0]->clientdata
) {
652 WWindow
*wwin
= (WWindow
*) scr
->window_menu
->entries
[0]->clientdata
;
654 wwin
->flags
.menu_open_for_me
= 0;
656 scr
->window_menu
->entries
[0]->clientdata
= NULL
;
660 static void updateMenuForWindow(WMenu
* menu
, WWindow
* wwin
)
662 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
665 updateOptionsMenu(menu
, wwin
);
666 updateMaximizeMenu(menu
, wwin
);
668 updateMakeShortcutMenu(menu
, wwin
);
670 wMenuSetEnabled(menu
, MC_HIDE
, wapp
!= NULL
&& !WFLAGP(wapp
->main_window_desc
, no_appicon
));
672 wMenuSetEnabled(menu
, MC_CLOSE
, (wwin
->protocols
.DELETE_WINDOW
&& !WFLAGP(wwin
, no_closable
)));
674 if (wwin
->flags
.miniaturized
) {
675 static char *text
= NULL
;
677 text
= _("Deminiaturize");
679 menu
->entries
[MC_MINIATURIZE
]->text
= text
;
681 static char *text
= NULL
;
683 text
= _("Miniaturize");
685 menu
->entries
[MC_MINIATURIZE
]->text
= text
;
688 wMenuSetEnabled(menu
, MC_MINIATURIZE
, !WFLAGP(wwin
, no_miniaturizable
));
690 if (wwin
->flags
.maximized
) {
691 static char *text
= NULL
;
693 text
= _("Unmaximize");
695 menu
->entries
[MC_MAXIMIZE
]->text
= text
;
696 updateUnmaximizeShortcut(menu
->entries
[MC_MAXIMIZE
], wwin
->flags
.maximized
);
698 static char *text
= NULL
;
700 text
= _("Maximize");
702 menu
->entries
[MC_MAXIMIZE
]->text
= text
;
703 menu
->entries
[MC_MAXIMIZE
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_MAXIMIZE
]);
705 wMenuSetEnabled(menu
, MC_MAXIMIZE
, IS_RESIZABLE(wwin
));
707 wMenuSetEnabled(menu
, MC_MOVERESIZE
, IS_RESIZABLE(wwin
)
708 && !wwin
->flags
.miniaturized
);
710 if (wwin
->flags
.shaded
) {
711 static char *text
= NULL
;
715 menu
->entries
[MC_SHADE
]->text
= text
;
717 static char *text
= NULL
;
721 menu
->entries
[MC_SHADE
]->text
= text
;
724 wMenuSetEnabled(menu
, MC_SHADE
, !WFLAGP(wwin
, no_shadeable
)
725 && !wwin
->flags
.miniaturized
);
727 if (wwin
->flags
.selected
) {
728 static char *text
= NULL
;
730 text
= _("Deselect");
732 menu
->entries
[MC_SELECT
]->text
= text
;
734 static char *text
= NULL
;
738 menu
->entries
[MC_SELECT
]->text
= text
;
741 wMenuSetEnabled(menu
, MC_DUMMY_MOVETO
, !IS_OMNIPRESENT(wwin
));
743 if (!wwin
->flags
.inspector_open
) {
744 wMenuSetEnabled(menu
, MC_PROPERTIES
, True
);
746 wMenuSetEnabled(menu
, MC_PROPERTIES
, False
);
749 /* Update shortcut labels except for (Un)Maximize which is
750 * handled separately.
752 menu
->entries
[MC_MINIATURIZE
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_MINIATURIZE
]);
753 menu
->entries
[MC_SHADE
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_SHADE
]);
754 menu
->entries
[MC_HIDE
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_HIDE
]);
755 menu
->entries
[MC_MOVERESIZE
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_MOVERESIZE
]);
756 menu
->entries
[MC_SELECT
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_SELECT
]);
757 menu
->entries
[MC_RELAUNCH
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_RELAUNCH
]);
758 menu
->entries
[MC_CLOSE
]->rtext
= GetShortcutKey(wKeyBindings
[WKBD_CLOSE
]);
760 /* set the client data of the entries to the window */
761 for (i
= 0; i
< menu
->entry_no
; i
++) {
762 menu
->entries
[i
]->clientdata
= wwin
;
765 for (i
= 0; i
< w_global
.workspace
.submenu
->entry_no
; i
++) {
766 w_global
.workspace
.submenu
->entries
[i
]->clientdata
= wwin
;
768 if (i
== w_global
.workspace
.current
)
769 wMenuSetEnabled(w_global
.workspace
.submenu
, i
, False
);
771 wMenuSetEnabled(w_global
.workspace
.submenu
, i
, True
);
774 menu
->flags
.realized
= 0;
778 static WMenu
*open_window_menu_core(WWindow
*wwin
)
780 WScreen
*scr
= wwin
->screen_ptr
;
783 wwin
->flags
.menu_open_for_me
= 1;
785 if (!scr
->window_menu
) {
786 scr
->window_menu
= createWindowMenu(scr
);
788 /* hack to save some memory allocation/deallocation */
789 wfree(scr
->window_menu
->entries
[MC_MINIATURIZE
]->text
);
790 wfree(scr
->window_menu
->entries
[MC_MAXIMIZE
]->text
);
791 wfree(scr
->window_menu
->entries
[MC_SHADE
]->text
);
792 wfree(scr
->window_menu
->entries
[MC_SELECT
]->text
);
794 updateWorkspaceMenu(w_global
.workspace
.submenu
);
797 menu
= scr
->window_menu
;
798 if (menu
->flags
.mapped
) {
800 if (menu
->entries
[0]->clientdata
== wwin
)
804 updateMenuForWindow(menu
, wwin
);
809 static void prepare_menu_position(WMenu
*menu
, int x
, int y
)
813 rect
= wGetRectForHead(menu
->frame
->screen_ptr
,
814 wGetHeadForPointerLocation(menu
->frame
->screen_ptr
));
815 if (x
< rect
.pos
.x
- menu
->frame
->core
->width
/ 2)
816 x
= rect
.pos
.x
- menu
->frame
->core
->width
/ 2;
821 void OpenWindowMenu(WWindow
*wwin
, int x
, int y
, int keyboard
)
825 menu
= open_window_menu_core(wwin
);
829 /* Specific menu position */
830 x
-= menu
->frame
->core
->width
/ 2;
831 if (x
+ menu
->frame
->core
->width
> wwin
->frame_x
+ wwin
->frame
->core
->width
)
832 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
- menu
->frame
->core
->width
;
833 if (x
< wwin
->frame_x
)
836 /* Common menu position */
837 prepare_menu_position(menu
, x
, y
);
839 if (!wwin
->flags
.internal_window
)
840 wMenuMapAt(menu
, x
, y
, keyboard
);
843 void OpenWindowMenu2(WWindow
*wwin
, int x
, int y
, int keyboard
)
848 menu
= open_window_menu_core(wwin
);
852 /* Specific menu position */
853 for (i
= 0; i
< w_global
.workspace
.submenu
->entry_no
; i
++) {
854 w_global
.workspace
.submenu
->entries
[i
]->clientdata
= wwin
;
855 wMenuSetEnabled(w_global
.workspace
.submenu
, i
, True
);
858 x
-= menu
->frame
->core
->width
/ 2;
860 /* Common menu position */
861 prepare_menu_position(menu
, x
, y
);
863 if (!wwin
->flags
.internal_window
)
864 wMenuMapAt(menu
, x
, y
, keyboard
);
867 void OpenMiniwindowMenu(WWindow
* wwin
, int x
, int y
)
871 menu
= open_window_menu_core(wwin
);
875 x
-= menu
->frame
->core
->width
/ 2;
877 wMenuMapAt(menu
, x
, y
, False
);
880 void DestroyWindowMenu(WScreen
*scr
)
882 if (scr
->window_menu
) {
883 scr
->window_menu
->entries
[MC_MINIATURIZE
]->text
= NULL
;
884 scr
->window_menu
->entries
[MC_MAXIMIZE
]->text
= NULL
;
885 scr
->window_menu
->entries
[MC_SHADE
]->text
= NULL
;
886 scr
->window_menu
->entries
[MC_SELECT
]->text
= NULL
;
887 wMenuDestroy(scr
->window_menu
, True
);
888 scr
->window_menu
= NULL
;