1 /* winmenu.c - command menu for windows
3 * Window Maker window manager
5 * Copyright (c) 1997, 1998 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
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
31 #include <X11/Xutil.h>
33 #include "WindowMaker.h"
39 #include "application.h"
42 #include "workspace.h"
43 #include "winspector.h"
47 #define MC_MINIATURIZE 1
50 #define MC_HIDE_OTHERS 4
52 #define MC_DUMMY_MOVETO 6
53 #define MC_PROPERTIES 7
60 /**** Global data ***/
61 extern Time LastTimestamp
;
62 extern Atom _XA_WM_DELETE_WINDOW
;
63 extern Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW
;
65 extern WShortKey wKeyBindings
[WKBD_LAST
];
67 extern WPreferences wPreferences
;
70 execMenuCommand(WMenu
*menu
, WMenuEntry
*entry
)
72 WWindow
*wwin
= (WWindow
*)entry
->clientdata
;
75 CloseWindowMenu(menu
->frame
->screen_ptr
);
77 switch (entry
->order
) {
79 /* send delete message */
80 wClientSendProtocol(wwin
, _XA_WM_DELETE_WINDOW
, LastTimestamp
);
84 if (wPreferences
.dont_confirm_kill
85 || wMessageDialog(menu
->frame
->screen_ptr
, _("Kill Application"),
86 _("This will kill the application.\nAny unsaved changes will be lost.\nPlease confirm."),
87 _("Yes"), _("No"), NULL
)==WAPRDefault
) {
88 if (!wwin
->flags
.destroyed
)
94 if (wwin
->protocols
.MINIATURIZE_WINDOW
) {
95 wClientSendProtocol(wwin
, _XA_GNUSTEP_WM_MINIATURIZE_WINDOW
,
102 if (wwin
->flags
.maximized
)
103 wUnmaximizeWindow(wwin
);
105 wMaximizeWindow(wwin
, MAX_VERTICAL
|MAX_HORIZONTAL
);
108 if (wwin
->flags
.shaded
)
109 wUnshadeWindow(wwin
);
117 if (wwin
->wm_class
|| wwin
->wm_instance
)
118 wShowInspectorForWindow(wwin
);
122 wapp
= wApplicationOf(wwin
->main_window
);
123 wHideApplication(wapp
);
126 wHideOtherApplications(wwin
);
133 switchWSCommand(WMenu
*menu
, WMenuEntry
*entry
)
135 WWindow
*wwin
= (WWindow
*)entry
->clientdata
;
137 if (wwin
->flags
.selected
)
139 wWindowChangeWorkspace(wwin
, entry
->order
);
144 updateWorkspaceMenu(WMenu
*menu
)
146 WScreen
*scr
= menu
->frame
->screen_ptr
;
147 char title
[MAX_WORKSPACENAME_WIDTH
+1];
153 for (i
=0; i
<scr
->workspace_count
; i
++) {
154 if (i
< menu
->entry_no
) {
155 if (strcmp(menu
->entries
[i
]->text
,scr
->workspaces
[i
]->name
)!=0) {
156 free(menu
->entries
[i
]->text
);
157 strcpy(title
, scr
->workspaces
[i
]->name
);
158 menu
->entries
[i
]->text
= wstrdup(title
);
159 menu
->flags
.realized
= 0;
162 strcpy(title
, scr
->workspaces
[i
]->name
);
164 wMenuAddCallback(menu
, title
, switchWSCommand
, NULL
);
166 menu
->flags
.realized
= 0;
170 if (!menu
->flags
.realized
)
176 makeWorkspaceMenu(WScreen
*scr
)
180 menu
= wMenuCreate(scr
, NULL
, False
);
182 wwarning(_("could not create workspace submenu for window menu"));
184 updateWorkspaceMenu(menu
);
191 createWindowMenu(WScreen
*scr
)
198 menu
= wMenuCreate(scr
, NULL
, False
);
200 * Warning: If you make some change that affects the order of the
201 * entries, you must update the command #defines in the top of
204 entry
= wMenuAddCallback(menu
, _("(Un)Maximize"), execMenuCommand
, NULL
);
205 if (wKeyBindings
[WKBD_MAXIMIZE
].keycode
!=0) {
206 kcode
= wKeyBindings
[WKBD_MAXIMIZE
].keycode
;
208 if (kcode
&& (tmp
= XKeysymToString(XKeycodeToKeysym(dpy
, kcode
, 0))))
209 entry
->rtext
= wstrdup(tmp
);
212 entry
= wMenuAddCallback(menu
, _("Miniaturize"), execMenuCommand
, NULL
);
214 if (wKeyBindings
[WKBD_MINIATURIZE
].keycode
!=0) {
215 kcode
= wKeyBindings
[WKBD_MINIATURIZE
].keycode
;
217 if (kcode
&& (tmp
= XKeysymToString(XKeycodeToKeysym(dpy
, kcode
, 0))))
218 entry
->rtext
= wstrdup(tmp
);
221 entry
= wMenuAddCallback(menu
, _("(Un)Shade"), execMenuCommand
, NULL
);
222 if (wKeyBindings
[WKBD_SHADE
].keycode
!=0) {
223 kcode
= wKeyBindings
[WKBD_SHADE
].keycode
;
225 if (kcode
&& (tmp
= XKeysymToString(XKeycodeToKeysym(dpy
, kcode
, 0))))
226 entry
->rtext
= wstrdup(tmp
);
229 entry
= wMenuAddCallback(menu
, _("Hide"), execMenuCommand
, NULL
);
230 if (wKeyBindings
[WKBD_HIDE
].keycode
!=0) {
231 kcode
= wKeyBindings
[WKBD_HIDE
].keycode
;
233 if (kcode
&& (tmp
= XKeysymToString(XKeycodeToKeysym(dpy
, kcode
, 0))))
234 entry
->rtext
= wstrdup(tmp
);
236 entry
= wMenuAddCallback(menu
, _("Hide Others"), execMenuCommand
, NULL
);
238 entry
= wMenuAddCallback(menu
, _("Select"), execMenuCommand
, NULL
);
239 if (wKeyBindings
[WKBD_SELECT
].keycode
!=0) {
240 kcode
= wKeyBindings
[WKBD_SELECT
].keycode
;
242 if (kcode
&& (tmp
= XKeysymToString(XKeycodeToKeysym(dpy
, kcode
, 0))))
243 entry
->rtext
= wstrdup(tmp
);
246 entry
= wMenuAddCallback(menu
, _("Move To"), NULL
, NULL
);
247 scr
->workspace_submenu
= makeWorkspaceMenu(scr
);
248 if (scr
->workspace_submenu
)
249 wMenuEntrySetCascade(menu
, entry
, scr
->workspace_submenu
);
251 entry
= wMenuAddCallback(menu
, _("Attributes..."), execMenuCommand
, NULL
);
253 entry
= wMenuAddCallback(menu
, _("Close"), execMenuCommand
, NULL
);
254 if (wKeyBindings
[WKBD_CLOSE
].keycode
!=0) {
255 kcode
= wKeyBindings
[WKBD_CLOSE
].keycode
;
256 if (kcode
&& (tmp
= XKeysymToString(XKeycodeToKeysym(dpy
, kcode
, 0))))
257 entry
->rtext
= wstrdup(tmp
);
260 entry
= wMenuAddCallback(menu
, _("Kill"), execMenuCommand
, NULL
);
267 CloseWindowMenu(WScreen
*scr
)
269 if (scr
->window_menu
&& scr
->window_menu
->flags
.mapped
)
270 wMenuUnmap(scr
->window_menu
);
276 OpenWindowMenu(WWindow
*wwin
, int x
, int y
, int keyboard
)
279 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
280 WScreen
*scr
= wwin
->screen_ptr
;
283 if (!scr
->window_menu
) {
284 scr
->window_menu
= createWindowMenu(scr
);
286 updateWorkspaceMenu(scr
->workspace_submenu
);
288 menu
= scr
->window_menu
;
289 if (menu
->flags
.mapped
) {
291 if (menu
->entries
[0]->clientdata
==wwin
) {
296 wMenuSetEnabled(menu
, MC_HIDE
, wapp
!=NULL
297 && !wapp
->main_window_desc
->window_flags
.no_appicon
);
299 wMenuSetEnabled(menu
, MC_CLOSE
,
300 (wwin
->protocols
.DELETE_WINDOW
301 && !wwin
->window_flags
.no_closable
));
303 wMenuSetEnabled(menu
, MC_MINIATURIZE
, !wwin
->window_flags
.no_miniaturizable
);
305 wMenuSetEnabled(menu
, MC_SHADE
, !wwin
->window_flags
.no_shadeable
);
307 wMenuSetEnabled(menu
, MC_DUMMY_MOVETO
, !wwin
->window_flags
.omnipresent
);
309 if ((wwin
->wm_class
|| wwin
->wm_instance
) && !wwin
->flags
.inspector_open
) {
310 wMenuSetEnabled(menu
, MC_PROPERTIES
, True
);
312 wMenuSetEnabled(menu
, MC_PROPERTIES
, False
);
315 /* set the client data of the entries to the window */
316 for (i
= 0; i
< menu
->entry_no
; i
++) {
317 menu
->entries
[i
]->clientdata
= wwin
;
319 for (i
= 0; i
< scr
->workspace_submenu
->entry_no
; i
++) {
320 scr
->workspace_submenu
->entries
[i
]->clientdata
= wwin
;
321 if (i
== scr
->current_workspace
) {
322 wMenuSetEnabled(scr
->workspace_submenu
, i
, False
);
324 wMenuSetEnabled(scr
->workspace_submenu
, i
, True
);
328 if (!menu
->flags
.realized
)
331 x
-= menu
->frame
->core
->width
/2;
332 if (x
+ menu
->frame
->core
->width
> wwin
->frame_x
+wwin
->frame
->core
->width
)
333 x
= wwin
->frame_x
+wwin
->frame
->core
->width
- menu
->frame
->core
->width
;
334 if (x
< wwin
->frame_x
)
337 if (!wwin
->flags
.internal_window
)
338 wMenuMapAt(menu
, x
, y
, keyboard
);