mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
...
This commit is contained in:
parent
7ecf21af70
commit
bf64e719a1
23
src/common.h
23
src/common.h
@ -24,6 +24,7 @@
|
||||
|
||||
/* Don't include GTK or core headers here */
|
||||
#include <X11/Xlib.h>
|
||||
#include <glib.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@ -39,4 +40,26 @@ typedef enum
|
||||
META_FRAME_MAXIMIZED = 1 << 9
|
||||
} MetaFrameFlags;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_MENU_OP_DELETE = 1 << 0,
|
||||
META_MENU_OP_MINIMIZE = 1 << 1,
|
||||
META_MENU_OP_UNMAXIMIZE = 1 << 2,
|
||||
META_MENU_OP_MAXIMIZE = 1 << 3,
|
||||
META_MENU_OP_UNSHADE = 1 << 4,
|
||||
META_MENU_OP_SHADE = 1 << 5,
|
||||
META_MENU_OP_UNSTICK = 1 << 6,
|
||||
META_MENU_OP_STICK = 1 << 7,
|
||||
META_MENU_OP_WORKSPACES = 1 << 8
|
||||
} MetaMenuOp;
|
||||
|
||||
typedef struct _MetaWindowMenu MetaWindowMenu;
|
||||
|
||||
typedef void (* MetaWindowMenuFunc) (MetaWindowMenu *menu,
|
||||
Display *xdisplay,
|
||||
Window client_xwindow,
|
||||
MetaMenuOp op,
|
||||
int workspace,
|
||||
gpointer data);
|
||||
|
||||
#endif
|
||||
|
20
src/core.c
20
src/core.c
@ -355,4 +355,24 @@ meta_core_get_frame_workspace (Display *xdisplay,
|
||||
return meta_window_get_net_wm_desktop (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
Time timestamp)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaWindow *window;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
window = meta_display_lookup_x_window (display, frame_xwindow);
|
||||
|
||||
if (window == NULL || window->frame == NULL)
|
||||
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
|
||||
|
||||
meta_window_show_menu (window, root_x, root_y, button, timestamp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -91,6 +91,13 @@ int meta_core_get_frame_workspace (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
|
||||
|
||||
void meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
Time timestamp);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -125,7 +125,9 @@ meta_display_open (const char *name)
|
||||
"_NET_WM_STATE_SKIP_TASKBAR",
|
||||
"_NET_WM_STATE_SKIP_PAGER",
|
||||
"_WIN_WORKSPACE",
|
||||
"_WIN_LAYER"
|
||||
"_WIN_LAYER",
|
||||
"_WIN_PROTOCOLS",
|
||||
"_WIN_SUPPORTING_WM_CHECK"
|
||||
};
|
||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||
|
||||
@ -200,6 +202,8 @@ meta_display_open (const char *name)
|
||||
display->atom_net_wm_state_skip_pager = atoms[31];
|
||||
display->atom_win_workspace = atoms[32];
|
||||
display->atom_win_layer = atoms[33];
|
||||
display->atom_win_protocols = atoms[34];
|
||||
display->atom_win_supporting_wm_check = atoms[35];
|
||||
|
||||
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
|
||||
* created in screen_new
|
||||
@ -268,7 +272,7 @@ meta_display_open (const char *name)
|
||||
|
||||
set_string_hint (display,
|
||||
display->leader_window,
|
||||
display->atom_net_supporting_wm_check,
|
||||
display->atom_net_wm_name,
|
||||
"Metacity");
|
||||
|
||||
/* Now manage all existing windows */
|
||||
|
@ -90,6 +90,8 @@ struct _MetaDisplay
|
||||
Atom atom_net_wm_state_skip_pager;
|
||||
Atom atom_win_workspace;
|
||||
Atom atom_win_layer;
|
||||
Atom atom_win_protocols;
|
||||
Atom atom_win_supporting_wm_check;
|
||||
|
||||
/* This is the actual window from focus events,
|
||||
* not the one we last set
|
||||
|
16
src/frame.c
16
src/frame.c
@ -27,7 +27,8 @@
|
||||
ExposureMask | \
|
||||
ButtonPressMask | ButtonReleaseMask | \
|
||||
PointerMotionMask | PointerMotionHintMask | \
|
||||
EnterWindowMask | LeaveWindowMask)
|
||||
EnterWindowMask | LeaveWindowMask | \
|
||||
FocusChangeMask)
|
||||
|
||||
void
|
||||
meta_window_ensure_frame (MetaWindow *window)
|
||||
@ -106,6 +107,9 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
meta_ui_set_frame_title (window->screen->ui,
|
||||
window->frame->xwindow,
|
||||
window->title);
|
||||
|
||||
/* Move keybindings to frame instead of window */
|
||||
meta_window_grab_keys (window);
|
||||
}
|
||||
|
||||
void
|
||||
@ -117,7 +121,7 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
return;
|
||||
|
||||
frame = window->frame;
|
||||
|
||||
|
||||
meta_ui_remove_frame (window->screen->ui, frame->xwindow);
|
||||
|
||||
/* Unparent the client window; it may be destroyed,
|
||||
@ -142,6 +146,9 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
|
||||
window->frame = NULL;
|
||||
|
||||
/* Move keybindings to window instead of frame */
|
||||
meta_window_grab_keys (window);
|
||||
|
||||
/* should we push an error trap? */
|
||||
XDestroyWindow (window->display->xdisplay, frame->xwindow);
|
||||
|
||||
@ -270,6 +277,8 @@ meta_frame_event (MetaFrame *frame,
|
||||
switch (event->type)
|
||||
{
|
||||
case KeyPress:
|
||||
meta_display_process_key_press (frame->window->display,
|
||||
frame->window, event);
|
||||
break;
|
||||
case KeyRelease:
|
||||
break;
|
||||
@ -290,8 +299,9 @@ meta_frame_event (MetaFrame *frame,
|
||||
case LeaveNotify:
|
||||
break;
|
||||
case FocusIn:
|
||||
break;
|
||||
case FocusOut:
|
||||
meta_window_notify_focus (frame->window,
|
||||
event);
|
||||
break;
|
||||
case KeymapNotify:
|
||||
break;
|
||||
|
22
src/frames.c
22
src/frames.c
@ -300,9 +300,6 @@ meta_frames_destroy (GtkObject *object)
|
||||
MetaFrames *frames;
|
||||
|
||||
frames = META_FRAMES (object);
|
||||
|
||||
if (frames->menu)
|
||||
gtk_widget_destroy (frames->menu);
|
||||
|
||||
winlist = NULL;
|
||||
g_hash_table_foreach (frames->frames,
|
||||
@ -856,13 +853,7 @@ meta_frames_end_grab (MetaFrames *frames,
|
||||
guint32 timestamp)
|
||||
{
|
||||
if (frames->grab_frame)
|
||||
{
|
||||
if (frames->grab_status == META_FRAME_STATUS_CLICKING_MENU)
|
||||
{
|
||||
if (frames->menu)
|
||||
gtk_widget_destroy (frames->menu);
|
||||
}
|
||||
|
||||
{
|
||||
frames->grab_frame = NULL;
|
||||
frames->grab_status = META_FRAME_STATUS_NORMAL;
|
||||
gdk_pointer_ungrab (timestamp);
|
||||
@ -1030,11 +1021,12 @@ meta_frames_button_press_event (GtkWidget *widget,
|
||||
|
||||
if (status == META_FRAME_STATUS_CLICKING_MENU)
|
||||
{
|
||||
meta_window_menu_show (frames, frame,
|
||||
event->x_root,
|
||||
event->y_root,
|
||||
event->button,
|
||||
event->time);
|
||||
meta_core_show_window_menu (gdk_display,
|
||||
frame->xwindow,
|
||||
event->x_root,
|
||||
event->y_root,
|
||||
event->button,
|
||||
event->time);
|
||||
}
|
||||
}
|
||||
else if (control == META_FRAME_CONTROL_RESIZE_SE &&
|
||||
|
@ -89,8 +89,6 @@ struct _MetaFrames
|
||||
int text_height;
|
||||
|
||||
GHashTable *frames;
|
||||
|
||||
GtkWidget *menu;
|
||||
|
||||
/* The below is all for grabs */
|
||||
MetaFrameStatus grab_status;
|
||||
@ -136,6 +134,7 @@ void meta_frames_get_pixmap_for_control (MetaFrames *frames,
|
||||
MetaFrameControl control,
|
||||
GdkPixmap **pixmap,
|
||||
GdkBitmap **mask);
|
||||
|
||||
void meta_frames_notify_menu_hide (MetaFrames *frames);
|
||||
|
||||
#endif
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "keybindings.h"
|
||||
#include "workspace.h"
|
||||
#include "errors.h"
|
||||
#include "ui.h"
|
||||
#include "frame.h"
|
||||
|
||||
#include <X11/keysym.h>
|
||||
|
||||
@ -30,12 +32,18 @@
|
||||
*/
|
||||
|
||||
typedef void (* MetaKeyHandler) (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
gpointer data);
|
||||
|
||||
static void handle_activate_workspace (MetaDisplay *display,
|
||||
XEvent *event,
|
||||
gpointer data);
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
gpointer data);
|
||||
static void handle_activate_menu (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
gpointer data);
|
||||
|
||||
typedef struct _MetaKeyBinding MetaKeyBinding;
|
||||
|
||||
@ -50,7 +58,7 @@ struct _MetaKeyBinding
|
||||
|
||||
#define INTERESTING_MODIFIERS (ShiftMask | ControlMask | Mod1Mask)
|
||||
|
||||
static MetaKeyBinding bindings[] = {
|
||||
static MetaKeyBinding screen_bindings[] = {
|
||||
{ XK_F1, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (0), 0 },
|
||||
{ XK_F2, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (1), 0 },
|
||||
{ XK_F3, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (2), 0 },
|
||||
@ -62,41 +70,57 @@ static MetaKeyBinding bindings[] = {
|
||||
{ XK_3, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (2), 0 },
|
||||
{ XK_4, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (3), 0 },
|
||||
{ XK_5, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (4), 0 },
|
||||
{ XK_6, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (5), 0 }
|
||||
{ XK_6, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (5), 0 },
|
||||
{ None, 0, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
void
|
||||
meta_display_init_keys (MetaDisplay *display)
|
||||
static MetaKeyBinding window_bindings[] = {
|
||||
{ XK_space, Mod1Mask, handle_activate_menu, NULL, 0 },
|
||||
{ None, 0, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
static void
|
||||
init_bindings (MetaDisplay *display,
|
||||
MetaKeyBinding *bindings)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < G_N_ELEMENTS (bindings))
|
||||
while (bindings[i].keysym != None)
|
||||
{
|
||||
bindings[i].keycode = XKeysymToKeycode (display->xdisplay,
|
||||
bindings[i].keysym);
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_grab_keys (MetaScreen *screen)
|
||||
meta_display_init_keys (MetaDisplay *display)
|
||||
{
|
||||
init_bindings (display, screen_bindings);
|
||||
init_bindings (display, window_bindings);
|
||||
}
|
||||
|
||||
static void
|
||||
grab_keys (MetaKeyBinding *bindings,
|
||||
MetaDisplay *display,
|
||||
Window xwindow)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < G_N_ELEMENTS (bindings))
|
||||
while (bindings[i].keysym != None)
|
||||
{
|
||||
if (bindings[i].keycode != 0)
|
||||
{
|
||||
int result;
|
||||
|
||||
meta_error_trap_push (screen->display);
|
||||
XGrabKey (screen->display->xdisplay, bindings[i].keycode,
|
||||
bindings[i].mask, screen->xroot, True,
|
||||
meta_error_trap_push (display);
|
||||
XGrabKey (display->xdisplay, bindings[i].keycode,
|
||||
bindings[i].mask, xwindow, True,
|
||||
GrabModeAsync, GrabModeAsync);
|
||||
result = meta_error_trap_pop (screen->display);
|
||||
result = meta_error_trap_pop (display);
|
||||
if (result != Success)
|
||||
{
|
||||
const char *name;
|
||||
@ -107,8 +131,6 @@ meta_screen_grab_keys (MetaScreen *screen)
|
||||
|
||||
if (result == BadAccess)
|
||||
meta_warning (_("Some other program is already using the key %s as a binding\n"), name);
|
||||
else
|
||||
meta_bug ("Unexpected error setting up keybindings\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,18 +138,22 @@ meta_screen_grab_keys (MetaScreen *screen)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_ungrab_keys (MetaScreen *screen)
|
||||
static void
|
||||
ungrab_keys (MetaKeyBinding *bindings,
|
||||
MetaDisplay *display,
|
||||
Window xwindow)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < G_N_ELEMENTS (bindings))
|
||||
while (bindings[i].keysym != None)
|
||||
{
|
||||
if (bindings[i].keycode != 0)
|
||||
{
|
||||
XUngrabKey (screen->display->xdisplay, bindings[i].keycode,
|
||||
bindings[i].mask, screen->xroot);
|
||||
meta_error_trap_push (display);
|
||||
XUngrabKey (display->xdisplay, bindings[i].keycode,
|
||||
bindings[i].mask, xwindow);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
++i;
|
||||
@ -135,8 +161,59 @@ meta_screen_ungrab_keys (MetaScreen *screen)
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_process_key_press (MetaDisplay *display,
|
||||
XEvent *event)
|
||||
meta_screen_grab_keys (MetaScreen *screen)
|
||||
{
|
||||
grab_keys (screen_bindings, screen->display, screen->xroot);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_ungrab_keys (MetaScreen *screen)
|
||||
{
|
||||
ungrab_keys (screen_bindings, screen->display, screen->xroot);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_grab_keys (MetaWindow *window)
|
||||
{
|
||||
if (window->keys_grabbed)
|
||||
{
|
||||
if (window->frame && !window->grab_on_frame)
|
||||
ungrab_keys (window_bindings, window->display,
|
||||
window->xwindow);
|
||||
else if (window->frame == NULL &&
|
||||
window->grab_on_frame)
|
||||
; /* continue to regrab on client window */
|
||||
else
|
||||
return; /* already all good */
|
||||
}
|
||||
|
||||
grab_keys (window_bindings, window->display,
|
||||
window->frame ? window->frame->xwindow : window->xwindow);
|
||||
|
||||
window->keys_grabbed = TRUE;
|
||||
window->grab_on_frame = window->frame != NULL;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_ungrab_keys (MetaWindow *window)
|
||||
{
|
||||
if (window->keys_grabbed)
|
||||
{
|
||||
if (window->grab_on_frame &&
|
||||
window->frame != NULL)
|
||||
ungrab_keys (window_bindings, window->display,
|
||||
window->frame->xwindow);
|
||||
else if (!window->grab_on_frame)
|
||||
ungrab_keys (window_bindings, window->display,
|
||||
window->xwindow);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_event (MetaKeyBinding *bindings,
|
||||
MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event)
|
||||
{
|
||||
KeySym keysym;
|
||||
int i;
|
||||
@ -144,22 +221,32 @@ meta_display_process_key_press (MetaDisplay *display,
|
||||
keysym = XKeycodeToKeysym (display->xdisplay, event->xkey.keycode, 0);
|
||||
|
||||
i = 0;
|
||||
while (i < G_N_ELEMENTS (bindings))
|
||||
while (bindings[i].keysym != None)
|
||||
{
|
||||
if (bindings[i].keysym == keysym &&
|
||||
((event->xkey.state & INTERESTING_MODIFIERS) ==
|
||||
bindings[i].mask))
|
||||
{
|
||||
(* bindings[i].handler) (display, event, bindings[i].data);
|
||||
(* bindings[i].handler) (display, window, event, bindings[i].data);
|
||||
break;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_process_key_press (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event)
|
||||
{
|
||||
process_event (screen_bindings, display, window, event);
|
||||
process_event (window_bindings, display, window, event);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_activate_workspace (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
@ -180,3 +267,22 @@ handle_activate_workspace (MetaDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_activate_menu (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
if (display->focus_window)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
meta_window_get_position (display->focus_window,
|
||||
&x, &y);
|
||||
|
||||
meta_window_show_menu (display->focus_window,
|
||||
x, y,
|
||||
0,
|
||||
event->xkey.time);
|
||||
}
|
||||
}
|
||||
|
@ -23,11 +23,15 @@
|
||||
#define META_KEYBINDINGS_H
|
||||
|
||||
#include "display.h"
|
||||
#include "window.h"
|
||||
|
||||
void meta_display_init_keys (MetaDisplay *display);
|
||||
void meta_screen_grab_keys (MetaScreen *screen);
|
||||
void meta_screen_ungrab_keys (MetaScreen *screen);
|
||||
void meta_window_grab_keys (MetaWindow *window);
|
||||
void meta_window_ungrab_keys (MetaWindow *window);
|
||||
void meta_display_process_key_press (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event);
|
||||
|
||||
#endif
|
||||
|
235
src/menu.c
235
src/menu.c
@ -27,19 +27,6 @@
|
||||
typedef struct _MenuItem MenuItem;
|
||||
typedef struct _MenuData MenuData;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_MENU_OP_DELETE = 1 << 0,
|
||||
META_MENU_OP_MINIMIZE = 1 << 1,
|
||||
META_MENU_OP_UNMAXIMIZE = 1 << 2,
|
||||
META_MENU_OP_MAXIMIZE = 1 << 3,
|
||||
META_MENU_OP_UNSHADE = 1 << 4,
|
||||
META_MENU_OP_SHADE = 1 << 5,
|
||||
META_MENU_OP_UNSTICK = 1 << 6,
|
||||
META_MENU_OP_STICK = 1 << 7,
|
||||
META_MENU_OP_WORKSPACES = 1 << 8
|
||||
} MetaMenuOp;
|
||||
|
||||
struct _MenuItem
|
||||
{
|
||||
MetaMenuOp op;
|
||||
@ -50,8 +37,7 @@ struct _MenuItem
|
||||
|
||||
struct _MenuData
|
||||
{
|
||||
MetaFrames *frames;
|
||||
MetaUIFrame *frame;
|
||||
MetaWindowMenu *menu;
|
||||
MetaMenuOp op;
|
||||
};
|
||||
|
||||
@ -92,70 +78,64 @@ popup_position_func (GtkMenu *menu,
|
||||
}
|
||||
|
||||
static void
|
||||
menu_closed (GtkMenu *menu,
|
||||
menu_closed (GtkMenu *widget,
|
||||
gpointer data)
|
||||
{
|
||||
MetaFrames *frames;
|
||||
MetaWindowMenu *menu;
|
||||
|
||||
menu = data;
|
||||
|
||||
frames = META_FRAMES (data);
|
||||
|
||||
meta_frames_notify_menu_hide (frames);
|
||||
|
||||
gtk_widget_destroy (frames->menu);
|
||||
frames->menu = NULL;
|
||||
meta_frames_notify_menu_hide (menu->frames);
|
||||
(* menu->func) (menu, gdk_display,
|
||||
menu->client_xwindow,
|
||||
0, 0,
|
||||
menu->data);
|
||||
|
||||
/* menu may now be freed */
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_menu_show (MetaFrames *frames,
|
||||
MetaUIFrame *frame,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp)
|
||||
static void
|
||||
activate_cb (GtkWidget *menuitem, gpointer data)
|
||||
{
|
||||
MenuData *md;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (menuitem));
|
||||
|
||||
md = data;
|
||||
|
||||
meta_frames_notify_menu_hide (md->menu->frames);
|
||||
(* md->menu->func) (md->menu, gdk_display,
|
||||
md->menu->client_xwindow,
|
||||
md->op,
|
||||
GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem),
|
||||
"workspace")),
|
||||
md->menu->data);
|
||||
|
||||
/* menu may now be freed */
|
||||
}
|
||||
|
||||
MetaWindowMenu*
|
||||
meta_window_menu_new (MetaFrames *frames,
|
||||
MetaMenuOp ops,
|
||||
MetaMenuOp insensitive,
|
||||
Window client_xwindow,
|
||||
int active_workspace,
|
||||
int n_workspaces,
|
||||
MetaWindowMenuFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
int i;
|
||||
GdkPoint *pt;
|
||||
int n_workspaces;
|
||||
int current_workspace;
|
||||
MetaMenuOp ops;
|
||||
MetaMenuOp insensitive;
|
||||
MetaFrameFlags flags;
|
||||
|
||||
flags = meta_core_get_frame_flags (gdk_display, frame->xwindow);
|
||||
|
||||
ops = 0;
|
||||
insensitive = 0;
|
||||
|
||||
if (flags & META_FRAME_ALLOWS_MAXIMIZE)
|
||||
{
|
||||
if (flags & META_FRAME_MAXIMIZED)
|
||||
ops |= META_MENU_OP_UNMAXIMIZE;
|
||||
else
|
||||
ops |= META_MENU_OP_MAXIMIZE;
|
||||
}
|
||||
MetaWindowMenu *menu;
|
||||
|
||||
if (flags & META_FRAME_SHADED)
|
||||
ops |= META_MENU_OP_UNSHADE;
|
||||
else
|
||||
ops |= META_MENU_OP_SHADE;
|
||||
|
||||
if (flags & META_FRAME_STUCK)
|
||||
ops |= META_MENU_OP_UNSTICK;
|
||||
else
|
||||
ops |= META_MENU_OP_STICK;
|
||||
menu = g_new (MetaWindowMenu, 1);
|
||||
menu->frames = frames;
|
||||
menu->client_xwindow = client_xwindow;
|
||||
menu->func = func;
|
||||
menu->data = data;
|
||||
menu->ops = ops;
|
||||
menu->insensitive = insensitive;
|
||||
|
||||
ops |= (META_MENU_OP_DELETE | META_MENU_OP_WORKSPACES | META_MENU_OP_MINIMIZE);
|
||||
|
||||
if (!(flags & META_FRAME_ALLOWS_MINIMIZE))
|
||||
insensitive |= META_MENU_OP_MINIMIZE;
|
||||
|
||||
if (!(flags & META_FRAME_ALLOWS_DELETE))
|
||||
insensitive |= META_MENU_OP_DELETE;
|
||||
|
||||
if (frames->menu)
|
||||
gtk_widget_destroy (frames->menu);
|
||||
|
||||
frames->menu = gtk_menu_new ();
|
||||
menu->menu = gtk_menu_new ();
|
||||
|
||||
i = 0;
|
||||
while (i < G_N_ELEMENTS (menuitems))
|
||||
@ -234,8 +214,7 @@ meta_window_menu_show (MetaFrames *frames,
|
||||
|
||||
md = g_new (MenuData, 1);
|
||||
|
||||
md->frames = frames;
|
||||
md->frame = frame;
|
||||
md->menu = menu;
|
||||
md->op = menuitems[i].op;
|
||||
|
||||
gtk_signal_connect_full (GTK_OBJECT (mi),
|
||||
@ -246,7 +225,7 @@ meta_window_menu_show (MetaFrames *frames,
|
||||
g_free, FALSE, FALSE);
|
||||
}
|
||||
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (frames->menu),
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu),
|
||||
mi);
|
||||
|
||||
gtk_widget_show (mi);
|
||||
@ -256,12 +235,8 @@ meta_window_menu_show (MetaFrames *frames,
|
||||
|
||||
if (ops & META_MENU_OP_WORKSPACES)
|
||||
{
|
||||
n_workspaces = meta_core_get_num_workspaces (DefaultScreenOfDisplay (gdk_display));
|
||||
current_workspace = meta_core_get_frame_workspace (gdk_display,
|
||||
frame->xwindow);
|
||||
|
||||
meta_warning ("Creating %d-workspace menu current %d\n",
|
||||
n_workspaces, current_workspace);
|
||||
n_workspaces, active_workspace);
|
||||
|
||||
if (n_workspaces > 0)
|
||||
{
|
||||
@ -273,7 +248,7 @@ meta_window_menu_show (MetaFrames *frames,
|
||||
char *label;
|
||||
MenuData *md;
|
||||
|
||||
if (flags & META_FRAME_STUCK)
|
||||
if (ops & META_MENU_OP_UNSTICK)
|
||||
label = g_strdup_printf (_("Only on workspace _%d\n"),
|
||||
i + 1);
|
||||
else
|
||||
@ -284,15 +259,14 @@ meta_window_menu_show (MetaFrames *frames,
|
||||
|
||||
g_free (label);
|
||||
|
||||
if (!(flags & META_FRAME_STUCK) &&
|
||||
(current_workspace == i ||
|
||||
if (!(ops & META_MENU_OP_UNSTICK) &&
|
||||
(active_workspace == i ||
|
||||
insensitive & META_MENU_OP_WORKSPACES))
|
||||
gtk_widget_set_sensitive (mi, FALSE);
|
||||
|
||||
md = g_new (MenuData, 1);
|
||||
|
||||
md->frames = frames;
|
||||
md->frame = frame;
|
||||
md->menu = menu;
|
||||
md->op = META_MENU_OP_WORKSPACES;
|
||||
|
||||
g_object_set_data (G_OBJECT (mi),
|
||||
@ -306,7 +280,7 @@ meta_window_menu_show (MetaFrames *frames,
|
||||
md,
|
||||
g_free, FALSE, FALSE);
|
||||
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (frames->menu),
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu),
|
||||
mi);
|
||||
|
||||
gtk_widget_show (mi);
|
||||
@ -318,14 +292,26 @@ meta_window_menu_show (MetaFrames *frames,
|
||||
else
|
||||
meta_verbose ("not creating workspace menu\n");
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (frames->menu),
|
||||
gtk_signal_connect (GTK_OBJECT (menu->menu),
|
||||
"selection_done",
|
||||
GTK_SIGNAL_FUNC (menu_closed),
|
||||
frames);
|
||||
menu);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_menu_popup (MetaWindowMenu *menu,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp)
|
||||
{
|
||||
GdkPoint *pt;
|
||||
|
||||
pt = g_new (GdkPoint, 1);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (frames->menu),
|
||||
g_object_set_data_full (G_OBJECT (menu->menu),
|
||||
"destroy-point",
|
||||
pt,
|
||||
g_free);
|
||||
@ -333,82 +319,19 @@ meta_window_menu_show (MetaFrames *frames,
|
||||
pt->x = root_x;
|
||||
pt->y = root_y;
|
||||
|
||||
gtk_menu_popup (GTK_MENU (frames->menu),
|
||||
gtk_menu_popup (GTK_MENU (menu->menu),
|
||||
NULL, NULL,
|
||||
popup_position_func, pt,
|
||||
button,
|
||||
timestamp);
|
||||
|
||||
if (!GTK_MENU_SHELL (frames->menu)->have_xgrab)
|
||||
if (!GTK_MENU_SHELL (menu->menu)->have_xgrab)
|
||||
meta_warning ("GtkMenu failed to grab the pointer\n");
|
||||
}
|
||||
|
||||
static void
|
||||
activate_cb (GtkWidget *menuitem, gpointer data)
|
||||
void
|
||||
meta_window_menu_free (MetaWindowMenu *menu)
|
||||
{
|
||||
MenuData *md;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (menuitem));
|
||||
|
||||
md = data;
|
||||
|
||||
switch (md->op)
|
||||
{
|
||||
case META_MENU_OP_DELETE:
|
||||
meta_core_delete (gdk_display,
|
||||
md->frame->xwindow,
|
||||
gtk_get_current_event_time ());
|
||||
break;
|
||||
|
||||
case META_MENU_OP_MINIMIZE:
|
||||
meta_core_minimize (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_UNMAXIMIZE:
|
||||
meta_core_unmaximize (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_MAXIMIZE:
|
||||
meta_core_maximize (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_UNSHADE:
|
||||
meta_core_unshade (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_SHADE:
|
||||
meta_core_shade (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_WORKSPACES:
|
||||
{
|
||||
int workspace;
|
||||
|
||||
workspace = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem),
|
||||
"workspace"));
|
||||
|
||||
meta_core_change_workspace (gdk_display, md->frame->xwindow,
|
||||
workspace);
|
||||
}
|
||||
break;
|
||||
|
||||
case META_MENU_OP_STICK:
|
||||
meta_core_stick (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_UNSTICK:
|
||||
meta_core_unstick (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
default:
|
||||
meta_warning (G_STRLOC": Unknown window op\n");
|
||||
break;
|
||||
}
|
||||
gtk_widget_destroy (menu->menu);
|
||||
g_free (menu);
|
||||
}
|
||||
|
31
src/menu.h
31
src/menu.h
@ -25,14 +25,31 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include "frames.h"
|
||||
|
||||
void meta_window_menu_show (MetaFrames *frames,
|
||||
MetaUIFrame *frame,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp);
|
||||
|
||||
struct _MetaWindowMenu
|
||||
{
|
||||
MetaFrames *frames;
|
||||
Window client_xwindow;
|
||||
GtkWidget *menu;
|
||||
MetaWindowMenuFunc func;
|
||||
gpointer data;
|
||||
MetaMenuOp ops;
|
||||
MetaMenuOp insensitive;
|
||||
};
|
||||
|
||||
MetaWindowMenu* meta_window_menu_new (MetaFrames *frames,
|
||||
MetaMenuOp ops,
|
||||
MetaMenuOp insensitive,
|
||||
Window client_xwindow,
|
||||
int active_workspace,
|
||||
int n_workspaces,
|
||||
MetaWindowMenuFunc func,
|
||||
gpointer data);
|
||||
void meta_window_menu_popup (MetaWindowMenu *menu,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp);
|
||||
void meta_window_menu_free (MetaWindowMenu *menu);
|
||||
|
||||
|
||||
#endif
|
||||
|
16
src/screen.c
16
src/screen.c
@ -50,6 +50,13 @@ set_wm_check_hint (MetaScreen *screen)
|
||||
screen->display->atom_net_supporting_wm_check,
|
||||
XA_WINDOW,
|
||||
32, PropModeReplace, (guchar*) data, 1);
|
||||
|
||||
/* Legacy GNOME hint */
|
||||
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||
screen->display->atom_win_supporting_wm_check,
|
||||
XA_WINDOW,
|
||||
32, PropModeReplace, (guchar*) data, 1);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
@ -57,6 +64,7 @@ static int
|
||||
set_supported_hint (MetaScreen *screen)
|
||||
{
|
||||
#define N_SUPPORTED 21
|
||||
#define N_WIN_SUPPORTED 1
|
||||
Atom atoms[N_SUPPORTED];
|
||||
|
||||
atoms[0] = screen->display->atom_net_wm_name;
|
||||
@ -86,6 +94,14 @@ set_supported_hint (MetaScreen *screen)
|
||||
XA_ATOM,
|
||||
32, PropModeReplace, (guchar*) atoms, N_SUPPORTED);
|
||||
|
||||
/* Set legacy GNOME hints */
|
||||
atoms[0] = screen->display->atom_win_layer;
|
||||
|
||||
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||
screen->display->atom_win_protocols,
|
||||
XA_ATOM,
|
||||
32, PropModeReplace, (guchar*) atoms, N_WIN_SUPPORTED);
|
||||
|
||||
return Success;
|
||||
#undef N_SUPPORTED
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ struct _MetaSessionInfo
|
||||
|
||||
MetaSessionInfo* meta_window_lookup_session_info (MetaWindow *window);
|
||||
|
||||
void meta_session_init (const char *previous_id);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
34
src/ui.c
34
src/ui.c
@ -22,6 +22,7 @@
|
||||
#include "ui.h"
|
||||
#include "frames.h"
|
||||
#include "util.h"
|
||||
#include "menu.h"
|
||||
|
||||
struct _MetaUI
|
||||
{
|
||||
@ -197,4 +198,37 @@ meta_ui_set_frame_title (MetaUI *ui,
|
||||
meta_frames_set_title (ui->frames, xwindow, title);
|
||||
}
|
||||
|
||||
MetaWindowMenu*
|
||||
meta_ui_window_menu_new (MetaUI *ui,
|
||||
Window client_xwindow,
|
||||
MetaMenuOp ops,
|
||||
MetaMenuOp insensitive,
|
||||
int active_workspace,
|
||||
int n_workspaces,
|
||||
MetaWindowMenuFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
return meta_window_menu_new (ui->frames,
|
||||
ops, insensitive,
|
||||
client_xwindow,
|
||||
active_workspace,
|
||||
n_workspaces,
|
||||
func, data);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_window_menu_popup (MetaWindowMenu *menu,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp)
|
||||
{
|
||||
meta_window_menu_popup (menu, root_x, root_y, button, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_window_menu_free (MetaWindowMenu *menu)
|
||||
{
|
||||
meta_window_menu_free (menu);
|
||||
}
|
||||
|
||||
|
17
src/ui.h
17
src/ui.h
@ -71,4 +71,21 @@ void meta_ui_set_frame_title (MetaUI *ui,
|
||||
Window xwindow,
|
||||
const char *title);
|
||||
|
||||
MetaWindowMenu* meta_ui_window_menu_new (MetaUI *ui,
|
||||
Window client_xwindow,
|
||||
MetaMenuOp ops,
|
||||
MetaMenuOp insensitive,
|
||||
int active_workspace,
|
||||
int n_workspaces,
|
||||
MetaWindowMenuFunc func,
|
||||
gpointer data);
|
||||
void meta_ui_window_menu_popup (MetaWindowMenu *menu,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp);
|
||||
void meta_ui_window_menu_free (MetaWindowMenu *menu);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
246
src/window.c
246
src/window.c
@ -25,6 +25,8 @@
|
||||
#include "errors.h"
|
||||
#include "workspace.h"
|
||||
#include "stack.h"
|
||||
#include "keybindings.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
@ -210,6 +212,8 @@ meta_window_new (MetaDisplay *display, Window xwindow,
|
||||
window->placed = window->mapped;
|
||||
window->unmanaging = FALSE;
|
||||
window->calc_showing_queued = FALSE;
|
||||
window->keys_grabbed = FALSE;
|
||||
window->grab_on_frame = FALSE;
|
||||
|
||||
window->unmaps_pending = 0;
|
||||
|
||||
@ -259,16 +263,19 @@ meta_window_new (MetaDisplay *display, Window xwindow,
|
||||
window->minimized = TRUE;
|
||||
meta_verbose ("Window %s asked to start out minimized\n", window->desc);
|
||||
}
|
||||
|
||||
|
||||
/* FIXME we have a tendency to set this then immediately
|
||||
* change it again.
|
||||
*/
|
||||
set_wm_state (window, window->iconic ? IconicState : NormalState);
|
||||
set_net_wm_state (window);
|
||||
|
||||
|
||||
/* keys grab on client window if no frame */
|
||||
if (window->decorated)
|
||||
meta_window_ensure_frame (window);
|
||||
|
||||
meta_window_grab_keys (window);
|
||||
|
||||
space =
|
||||
meta_display_get_workspace_by_screen_index (window->display,
|
||||
window->screen,
|
||||
@ -321,6 +328,9 @@ meta_window_free (MetaWindow *window)
|
||||
meta_verbose ("Unmanaging 0x%lx\n", window->xwindow);
|
||||
|
||||
window->unmanaging = TRUE;
|
||||
|
||||
if (window->display->focus_window == window)
|
||||
window->display->focus_window = NULL;
|
||||
|
||||
meta_window_unqueue_calc_showing (window);
|
||||
|
||||
@ -343,12 +353,15 @@ meta_window_free (MetaWindow *window)
|
||||
|
||||
/* FIXME restore original size if window has maximized */
|
||||
|
||||
set_wm_state (window, WithdrawnState);
|
||||
|
||||
set_wm_state (window, WithdrawnState);
|
||||
|
||||
if (window->frame)
|
||||
meta_window_destroy_frame (window);
|
||||
|
||||
meta_window_ungrab_keys (window);
|
||||
|
||||
meta_display_unregister_x_window (window->display, window->xwindow);
|
||||
|
||||
meta_window_destroy_frame (window);
|
||||
|
||||
|
||||
/* Put back anything we messed up */
|
||||
meta_error_trap_push (window->display);
|
||||
if (window->border_width != 0)
|
||||
@ -698,9 +711,13 @@ meta_window_unmaximize (MetaWindow *window)
|
||||
void
|
||||
meta_window_shade (MetaWindow *window)
|
||||
{
|
||||
meta_verbose ("Shading %s\n", window->desc);
|
||||
if (!window->shaded)
|
||||
{
|
||||
window->shaded = TRUE;
|
||||
|
||||
meta_window_focus (window, CurrentTime);
|
||||
|
||||
meta_window_queue_move_resize (window);
|
||||
meta_window_queue_calc_showing (window);
|
||||
|
||||
@ -711,6 +728,7 @@ meta_window_shade (MetaWindow *window)
|
||||
void
|
||||
meta_window_unshade (MetaWindow *window)
|
||||
{
|
||||
meta_verbose ("Unshading %s\n", window->desc);
|
||||
if (window->shaded)
|
||||
{
|
||||
window->shaded = FALSE;
|
||||
@ -1153,24 +1171,41 @@ meta_window_focus (MetaWindow *window,
|
||||
meta_verbose ("Setting input focus to window %s, input: %d take_focus: %d\n",
|
||||
window->desc, window->input, window->take_focus);
|
||||
|
||||
meta_error_trap_push (window->display);
|
||||
|
||||
if (window->input)
|
||||
if (window->shaded && window->frame)
|
||||
{
|
||||
XSetInputFocus (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
RevertToPointerRoot,
|
||||
timestamp);
|
||||
/* This is so we can still use keyboard shortcuts
|
||||
* and still draw the window as focused.
|
||||
*/
|
||||
if (window->frame)
|
||||
{
|
||||
meta_verbose ("Focusing frame of %s\n", window->desc);
|
||||
XSetInputFocus (window->display->xdisplay,
|
||||
window->frame->xwindow,
|
||||
RevertToPointerRoot,
|
||||
CurrentTime);
|
||||
}
|
||||
}
|
||||
|
||||
if (window->take_focus)
|
||||
else
|
||||
{
|
||||
meta_window_send_icccm_message (window,
|
||||
window->display->atom_wm_take_focus,
|
||||
timestamp);
|
||||
meta_error_trap_push (window->display);
|
||||
|
||||
if (window->input)
|
||||
{
|
||||
XSetInputFocus (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
RevertToPointerRoot,
|
||||
timestamp);
|
||||
}
|
||||
|
||||
if (window->take_focus)
|
||||
{
|
||||
meta_window_send_icccm_message (window,
|
||||
window->display->atom_wm_take_focus,
|
||||
timestamp);
|
||||
}
|
||||
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1504,6 +1539,34 @@ meta_window_client_message (MetaWindow *window,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_window_notify_focus (MetaWindow *window,
|
||||
XEvent *event)
|
||||
{
|
||||
/* note the event can be on either the window or the frame,
|
||||
* we focus the frame for shaded windows
|
||||
*/
|
||||
|
||||
if (event->type == FocusIn)
|
||||
{
|
||||
if (window != window->display->focus_window)
|
||||
window->display->focus_window = window;
|
||||
window->has_focus = TRUE;
|
||||
if (window->frame)
|
||||
meta_frame_queue_draw (window->frame);
|
||||
}
|
||||
else if (event->type == FocusOut)
|
||||
{
|
||||
if (window == window->display->focus_window)
|
||||
window->display->focus_window = NULL;
|
||||
window->has_focus = FALSE;
|
||||
if (window->frame)
|
||||
meta_frame_queue_draw (window->frame);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_property_notify (MetaWindow *window,
|
||||
XPropertyEvent *event)
|
||||
@ -2797,3 +2860,144 @@ constrain_position (MetaWindow *window,
|
||||
*new_x = x;
|
||||
*new_y = y;
|
||||
}
|
||||
|
||||
static void
|
||||
menu_callback (MetaWindowMenu *menu,
|
||||
Display *xdisplay,
|
||||
Window client_xwindow,
|
||||
MetaMenuOp op,
|
||||
int workspace_index,
|
||||
gpointer data)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaWindow *window;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
window = meta_display_lookup_x_window (display, client_xwindow);
|
||||
|
||||
if (window != NULL) /* window can be NULL */
|
||||
{
|
||||
meta_verbose ("Menu op %d on %s\n", op, window->desc);
|
||||
|
||||
/* op can be 0 for none */
|
||||
switch (op)
|
||||
{
|
||||
case META_MENU_OP_DELETE:
|
||||
meta_window_delete (window, CurrentTime);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_MINIMIZE:
|
||||
meta_window_minimize (window);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_UNMAXIMIZE:
|
||||
meta_window_unmaximize (window);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_MAXIMIZE:
|
||||
meta_window_maximize (window);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_UNSHADE:
|
||||
meta_window_unshade (window);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_SHADE:
|
||||
meta_window_shade (window);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_WORKSPACES:
|
||||
{
|
||||
MetaWorkspace *workspace;
|
||||
|
||||
workspace =
|
||||
meta_display_get_workspace_by_screen_index (window->display,
|
||||
window->screen,
|
||||
workspace_index);
|
||||
|
||||
if (workspace)
|
||||
meta_window_change_workspace (window,
|
||||
workspace);
|
||||
else
|
||||
meta_warning ("Workspace %d doesn't exist\n", workspace_index);
|
||||
}
|
||||
break;
|
||||
|
||||
case META_MENU_OP_STICK:
|
||||
meta_window_stick (window);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_UNSTICK:
|
||||
meta_window_unstick (window);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
/* nothing */
|
||||
break;
|
||||
|
||||
default:
|
||||
meta_warning (G_STRLOC": Unknown window op\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_verbose ("Menu callback on nonexistent window\n");
|
||||
}
|
||||
|
||||
meta_ui_window_menu_free (menu);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_show_menu (MetaWindow *window,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
Time timestamp)
|
||||
{
|
||||
MetaMenuOp ops;
|
||||
MetaMenuOp insensitive;
|
||||
MetaWindowMenu *menu;
|
||||
|
||||
ops = 0;
|
||||
insensitive = 0;
|
||||
|
||||
ops |= (META_MENU_OP_DELETE | META_MENU_OP_WORKSPACES | META_MENU_OP_MINIMIZE);
|
||||
|
||||
if (window->maximized)
|
||||
ops |= META_MENU_OP_UNMAXIMIZE;
|
||||
else
|
||||
ops |= META_MENU_OP_MAXIMIZE;
|
||||
|
||||
if (!window->has_maximize_func)
|
||||
insensitive |= META_MENU_OP_UNMAXIMIZE | META_MENU_OP_MAXIMIZE;
|
||||
|
||||
if (window->shaded)
|
||||
ops |= META_MENU_OP_UNSHADE;
|
||||
else
|
||||
ops |= META_MENU_OP_SHADE;
|
||||
|
||||
if (window->on_all_workspaces)
|
||||
ops |= META_MENU_OP_UNSTICK;
|
||||
else
|
||||
ops |= META_MENU_OP_STICK;
|
||||
|
||||
if (!window->has_minimize_func)
|
||||
insensitive |= META_MENU_OP_MINIMIZE;
|
||||
|
||||
if (!window->has_close_func)
|
||||
insensitive |= META_MENU_OP_DELETE;
|
||||
|
||||
menu =
|
||||
meta_ui_window_menu_new (window->screen->ui,
|
||||
window->xwindow,
|
||||
ops,
|
||||
insensitive,
|
||||
meta_window_get_net_wm_desktop (window),
|
||||
meta_screen_get_n_workspaces (window->screen),
|
||||
menu_callback,
|
||||
NULL);
|
||||
|
||||
meta_verbose ("Popping up window menu for %s\n", window->desc);
|
||||
meta_ui_window_menu_popup (menu, root_x, root_y, button, timestamp);
|
||||
}
|
||||
|
13
src/window.h
13
src/window.h
@ -139,6 +139,10 @@ struct _MetaWindow
|
||||
|
||||
/* Are we in the calc_showing queue? */
|
||||
guint calc_showing_queued : 1;
|
||||
|
||||
/* Used by keybindings.c */
|
||||
guint keys_grabbed : 1;
|
||||
guint grab_on_frame : 1;
|
||||
|
||||
/* Number of UnmapNotify that are caused by us, if
|
||||
* we get UnmapNotify with none pending then the client
|
||||
@ -227,8 +231,17 @@ gboolean meta_window_property_notify (MetaWindow *window,
|
||||
XEvent *event);
|
||||
gboolean meta_window_client_message (MetaWindow *window,
|
||||
XEvent *event);
|
||||
gboolean meta_window_notify_focus (MetaWindow *window,
|
||||
XEvent *event);
|
||||
|
||||
int meta_window_set_current_workspace_hint (MetaWindow *window);
|
||||
|
||||
unsigned long meta_window_get_net_wm_desktop (MetaWindow *window);
|
||||
|
||||
void meta_window_show_menu (MetaWindow *window,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
Time timestamp);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user