...
This commit is contained in:
parent
5611d75a11
commit
9e9ffdca42
122
src/core.c
122
src/core.c
@ -21,6 +21,7 @@
|
||||
|
||||
#include "core.h"
|
||||
#include "frame.h"
|
||||
#include "workspace.h"
|
||||
|
||||
void
|
||||
meta_core_get_frame_size (Display *xdisplay,
|
||||
@ -234,3 +235,124 @@ meta_core_delete (Display *xdisplay,
|
||||
meta_window_delete (window, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_unshade (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
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_unshade (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_shade (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
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_shade (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_unstick (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
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_unstick (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_stick (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
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_stick (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_change_workspace (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int new_workspace)
|
||||
{
|
||||
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_change_workspace (window,
|
||||
meta_display_get_workspace_by_screen_index (display,
|
||||
window->screen,
|
||||
new_workspace));
|
||||
}
|
||||
|
||||
int
|
||||
meta_core_get_num_workspaces (Screen *xscreen)
|
||||
{
|
||||
MetaScreen *screen;
|
||||
|
||||
screen = meta_screen_for_x_screen (xscreen);
|
||||
|
||||
return meta_screen_get_n_workspaces (screen);
|
||||
}
|
||||
|
||||
int
|
||||
meta_core_get_active_workspace (Screen *xscreen)
|
||||
{
|
||||
MetaScreen *screen;
|
||||
|
||||
screen = meta_screen_for_x_screen (xscreen);
|
||||
|
||||
return meta_workspace_screen_index (screen->active_workspace);
|
||||
}
|
||||
|
||||
int
|
||||
meta_core_get_frame_workspace (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
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);
|
||||
|
||||
return meta_window_get_net_wm_desktop (window);
|
||||
}
|
||||
|
||||
|
||||
|
@ -85,10 +85,8 @@ void meta_core_change_workspace (Display *xdisplay,
|
||||
int new_workspace);
|
||||
|
||||
|
||||
int meta_core_get_num_workspaces (Display *xdisplay,
|
||||
Screen *xscreen);
|
||||
int meta_core_get_active_workspace (Display *xdisplay,
|
||||
Screen *xscreen);
|
||||
int meta_core_get_num_workspaces (Screen *xscreen);
|
||||
int meta_core_get_active_workspace (Screen *xscreen);
|
||||
int meta_core_get_frame_workspace (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
|
||||
|
@ -99,7 +99,7 @@ meta_display_open (const char *name)
|
||||
"WM_STATE",
|
||||
"_NET_CLOSE_WINDOW",
|
||||
"_NET_WM_STATE",
|
||||
"MOTIF_WM_HINTS",
|
||||
"_MOTIF_WM_HINTS",
|
||||
"_NET_WM_STATE_SHADED",
|
||||
"_NET_WM_STATE_MAXIMIZED_HORZ",
|
||||
"_NET_WM_STATE_MAXIMIZED_VERT",
|
||||
@ -124,7 +124,8 @@ meta_display_open (const char *name)
|
||||
"_NET_CLIENT_LIST_STACKING",
|
||||
"_NET_WM_STATE_SKIP_TASKBAR",
|
||||
"_NET_WM_STATE_SKIP_PAGER",
|
||||
"_WIN_WORKSPACE"
|
||||
"_WIN_WORKSPACE",
|
||||
"_WIN_LAYER"
|
||||
};
|
||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||
|
||||
@ -198,6 +199,7 @@ meta_display_open (const char *name)
|
||||
display->atom_net_wm_state_skip_taskbar = atoms[30];
|
||||
display->atom_net_wm_state_skip_pager = atoms[31];
|
||||
display->atom_win_workspace = atoms[32];
|
||||
display->atom_win_layer = atoms[33];
|
||||
|
||||
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
|
||||
* created in screen_new
|
||||
|
@ -89,6 +89,7 @@ struct _MetaDisplay
|
||||
Atom atom_net_wm_state_skip_taskbar;
|
||||
Atom atom_net_wm_state_skip_pager;
|
||||
Atom atom_win_workspace;
|
||||
Atom atom_win_layer;
|
||||
|
||||
/* This is the actual window from focus events,
|
||||
* not the one we last set
|
||||
|
@ -64,6 +64,7 @@ meta_error_trap_pop (MetaDisplay *display)
|
||||
ErrorTrap *et;
|
||||
GSList *next;
|
||||
|
||||
XSync (display->xdisplay, False);
|
||||
return gdk_error_trap_pop ();
|
||||
/* below here is old method */
|
||||
|
||||
|
40
src/frames.c
40
src/frames.c
@ -359,6 +359,20 @@ queue_recalc_func (gpointer key, gpointer value, gpointer data)
|
||||
gdk_window_invalidate_rect (frame->window, NULL, FALSE);
|
||||
meta_core_queue_frame_resize (gdk_display,
|
||||
frame->xwindow);
|
||||
if (frame->layout)
|
||||
{
|
||||
/* recreate layout */
|
||||
char *text;
|
||||
|
||||
text = g_strdup (pango_layout_get_text (frame->layout));
|
||||
|
||||
g_object_unref (G_OBJECT (frame->layout));
|
||||
|
||||
frame->layout = gtk_widget_create_pango_layout (GTK_WIDGET (frames),
|
||||
text);
|
||||
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -946,9 +960,6 @@ meta_frames_button_press_event (GtkWidget *widget,
|
||||
MetaFrameControl control;
|
||||
|
||||
frames = META_FRAMES (widget);
|
||||
|
||||
if (frames->grab_frame != NULL)
|
||||
return FALSE; /* already up to something */
|
||||
|
||||
frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
|
||||
if (frame == NULL)
|
||||
@ -956,6 +967,27 @@ meta_frames_button_press_event (GtkWidget *widget,
|
||||
|
||||
control = get_control (frames, frame, event->x, event->y);
|
||||
|
||||
if (control == META_FRAME_CONTROL_TITLE &&
|
||||
event->button == 1 &&
|
||||
event->type == GDK_2BUTTON_PRESS)
|
||||
{
|
||||
MetaFrameFlags flags;
|
||||
|
||||
flags = meta_core_get_frame_flags (gdk_display, frame->xwindow);
|
||||
|
||||
if (flags & META_FRAME_SHADED)
|
||||
meta_core_unshade (gdk_display,
|
||||
frame->xwindow);
|
||||
else
|
||||
meta_core_shade (gdk_display,
|
||||
frame->xwindow);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (frames->grab_frame != NULL)
|
||||
return FALSE; /* already up to something */
|
||||
|
||||
if (event->button == 1)
|
||||
meta_core_user_raise (gdk_display, frame->xwindow);
|
||||
|
||||
@ -1006,7 +1038,7 @@ meta_frames_button_press_event (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
else if (control == META_FRAME_CONTROL_RESIZE_SE &&
|
||||
event->button == 1)
|
||||
event->button == 1)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
|
@ -89,6 +89,8 @@ struct _MetaFrames
|
||||
int text_height;
|
||||
|
||||
GHashTable *frames;
|
||||
|
||||
GtkWidget *menu;
|
||||
|
||||
/* The below is all for grabs */
|
||||
MetaFrameStatus grab_status;
|
||||
@ -130,4 +132,10 @@ void meta_frames_reset_bg (MetaFrames *frames,
|
||||
void meta_frames_queue_draw (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
|
||||
void meta_frames_get_pixmap_for_control (MetaFrames *frames,
|
||||
MetaFrameControl control,
|
||||
GdkPixmap **pixmap,
|
||||
GdkBitmap **mask);
|
||||
void meta_frames_notify_menu_hide (MetaFrames *frames);
|
||||
|
||||
#endif
|
||||
|
435
src/menu.c
435
src/menu.c
@ -21,6 +21,8 @@
|
||||
|
||||
#include "menu.h"
|
||||
#include "main.h"
|
||||
#include "util.h"
|
||||
#include "core.h"
|
||||
|
||||
typedef struct _MenuItem MenuItem;
|
||||
typedef struct _MenuData MenuData;
|
||||
@ -48,23 +50,23 @@ struct _MenuItem
|
||||
|
||||
struct _MenuData
|
||||
{
|
||||
GdkWindow *window;
|
||||
MetaMessageWindowMenuOps op;
|
||||
MetaFrames *frames;
|
||||
MetaUIFrame *frame;
|
||||
MetaMenuOp op;
|
||||
};
|
||||
|
||||
static void activate_cb (GtkWidget *menuitem, gpointer data);
|
||||
|
||||
static GtkWidget *menu = NULL;
|
||||
static MenuItem menuitems[] = {
|
||||
{ META_MESSAGE_MENU_DELETE, GTK_STOCK_CLOSE, N_("_Close") },
|
||||
{ META_MESSAGE_MENU_MINIMIZE, NULL, N_("_Minimize") },
|
||||
{ META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Ma_ximize") },
|
||||
{ META_MESSAGE_MENU_UNMAXIMIZE, NULL, N_("_Unmaximize") },
|
||||
{ META_MESSAGE_MENU_SHADE, NULL, N_("_Shade") },
|
||||
{ META_MESSAGE_MENU_UNSHADE, NULL, N_("U_nshade") },
|
||||
{ META_MENU_OP_DELETE, NULL, N_("_Close") },
|
||||
{ META_MENU_OP_MINIMIZE, NULL, N_("_Minimize") },
|
||||
{ META_MENU_OP_MAXIMIZE, NULL, N_("Ma_ximize") },
|
||||
{ META_MENU_OP_UNMAXIMIZE, NULL, N_("_Unmaximize") },
|
||||
{ META_MENU_OP_SHADE, NULL, N_("_Shade") },
|
||||
{ META_MENU_OP_UNSHADE, NULL, N_("U_nshade") },
|
||||
{ 0, NULL, NULL }, /* separator */
|
||||
{ META_MESSAGE_MENU_STICK, NULL, N_("Put on _All Workspaces") },
|
||||
{ META_MESSAGE_MENU_UNSTICK, NULL, N_("Only on _This Workspace") }
|
||||
{ META_MENU_OP_STICK, NULL, N_("Put on _All Workspaces") },
|
||||
{ META_MENU_OP_UNSTICK, NULL, N_("Only on _This Workspace") }
|
||||
};
|
||||
|
||||
static void
|
||||
@ -89,121 +91,71 @@ popup_position_func (GtkMenu *menu,
|
||||
*y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
|
||||
}
|
||||
|
||||
static gint
|
||||
get_num_desktops (void)
|
||||
{
|
||||
Atom type;
|
||||
gint format;
|
||||
gulong nitems;
|
||||
gulong bytes_after;
|
||||
gulong *num;
|
||||
int result;
|
||||
|
||||
XGetWindowProperty (gdk_display, gdk_root_window,
|
||||
gdk_atom_intern ("_NET_NUMBER_OF_DESKTOPS", FALSE),
|
||||
0, G_MAXLONG,
|
||||
False, XA_CARDINAL, &type, &format, &nitems,
|
||||
&bytes_after, (guchar **)&num);
|
||||
static void
|
||||
menu_closed (GtkMenu *menu,
|
||||
gpointer data)
|
||||
{
|
||||
MetaFrames *frames;
|
||||
|
||||
if (type != XA_CARDINAL)
|
||||
return 0;
|
||||
frames = META_FRAMES (data);
|
||||
|
||||
result = *num;
|
||||
|
||||
XFree (num);
|
||||
meta_frames_notify_menu_hide (frames);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gint
|
||||
get_active_desktop (void)
|
||||
{
|
||||
Atom type;
|
||||
gint format;
|
||||
gulong nitems;
|
||||
gulong bytes_after;
|
||||
gulong *num;
|
||||
int result;
|
||||
|
||||
XGetWindowProperty (gdk_display, gdk_root_window,
|
||||
gdk_atom_intern ("_NET_CURRENT_DESKTOP", FALSE),
|
||||
0, G_MAXLONG,
|
||||
False, XA_CARDINAL, &type, &format, &nitems,
|
||||
&bytes_after, (guchar **)&num);
|
||||
|
||||
if (type != XA_CARDINAL)
|
||||
return 0;
|
||||
|
||||
result = *num;
|
||||
|
||||
XFree (num);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gulong
|
||||
get_current_desktop (GdkWindow *window)
|
||||
{
|
||||
Atom type;
|
||||
gint format;
|
||||
gulong nitems;
|
||||
gulong bytes_after;
|
||||
gulong *num;
|
||||
gulong result;
|
||||
int err;
|
||||
|
||||
gdk_error_trap_push ();
|
||||
type = None;
|
||||
XGetWindowProperty (gdk_display, GDK_WINDOW_XID (window),
|
||||
gdk_atom_intern ("_NET_WM_DESKTOP", FALSE),
|
||||
0, G_MAXLONG,
|
||||
False, XA_CARDINAL, &type, &format, &nitems,
|
||||
&bytes_after, (guchar **)&num);
|
||||
err = gdk_error_trap_pop ();
|
||||
if (err != Success)
|
||||
meta_ui_warning ("Error %d getting _NET_WM_DESKTOP\n", err);
|
||||
|
||||
if (type != XA_CARDINAL)
|
||||
{
|
||||
meta_ui_warning ("_NET_WM_DESKTOP has wrong type %s\n", gdk_atom_name (type));
|
||||
return 0xFFFFFFFF; /* sticky */
|
||||
}
|
||||
|
||||
result = *num;
|
||||
|
||||
XFree (num);
|
||||
|
||||
return result;
|
||||
gtk_widget_destroy (frames->menu);
|
||||
frames->menu = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_menu_show (gulong xwindow,
|
||||
int root_x, int root_y,
|
||||
int button,
|
||||
MetaMessageWindowMenuOps ops,
|
||||
MetaMessageWindowMenuOps insensitive,
|
||||
guint32 timestamp)
|
||||
meta_window_menu_show (MetaFrames *frames,
|
||||
MetaUIFrame *frame,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp)
|
||||
{
|
||||
int i;
|
||||
GdkWindow *window;
|
||||
GdkPoint *pt;
|
||||
int n_workspaces;
|
||||
int current_workspace;
|
||||
MetaMenuOp ops;
|
||||
MetaMenuOp insensitive;
|
||||
MetaFrameFlags flags;
|
||||
|
||||
if (menu)
|
||||
gtk_widget_destroy (menu);
|
||||
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;
|
||||
}
|
||||
|
||||
window = gdk_xid_table_lookup (xwindow);
|
||||
if (window)
|
||||
g_object_ref (G_OBJECT (window));
|
||||
if (flags & META_FRAME_SHADED)
|
||||
ops |= META_MENU_OP_UNSHADE;
|
||||
else
|
||||
window = gdk_window_foreign_new (xwindow);
|
||||
ops |= META_MENU_OP_SHADE;
|
||||
|
||||
/* X error creating the foreign window means NULL here */
|
||||
if (window == NULL)
|
||||
return;
|
||||
if (flags & META_FRAME_STUCK)
|
||||
ops |= META_MENU_OP_UNSTICK;
|
||||
else
|
||||
ops |= META_MENU_OP_STICK;
|
||||
|
||||
menu = gtk_menu_new ();
|
||||
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 ();
|
||||
|
||||
i = 0;
|
||||
while (i < G_N_ELEMENTS (menuitems))
|
||||
@ -219,13 +171,55 @@ meta_window_menu_show (gulong xwindow,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (menuitems[i].stock_id)
|
||||
GtkWidget *image;
|
||||
GdkPixmap *pix;
|
||||
GdkBitmap *mask;
|
||||
|
||||
image = NULL;
|
||||
pix = NULL;
|
||||
mask = NULL;
|
||||
|
||||
switch (menuitems[i].op)
|
||||
{
|
||||
GtkWidget *image;
|
||||
case META_MENU_OP_MAXIMIZE:
|
||||
meta_frames_get_pixmap_for_control (frames,
|
||||
META_FRAME_CONTROL_MAXIMIZE,
|
||||
&pix, &mask);
|
||||
break;
|
||||
|
||||
mi = gtk_image_menu_item_new_with_mnemonic (menuitems[i].label);
|
||||
case META_MENU_OP_MINIMIZE:
|
||||
meta_frames_get_pixmap_for_control (frames,
|
||||
META_FRAME_CONTROL_MINIMIZE,
|
||||
&pix, &mask);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_DELETE:
|
||||
meta_frames_get_pixmap_for_control (frames,
|
||||
META_FRAME_CONTROL_DELETE,
|
||||
&pix, &mask);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (pix)
|
||||
{
|
||||
image = gtk_image_new_from_pixmap (pix, mask);
|
||||
g_object_unref (G_OBJECT (pix));
|
||||
g_object_unref (G_OBJECT (mask));
|
||||
}
|
||||
|
||||
if (image == NULL &&
|
||||
menuitems[i].stock_id)
|
||||
{
|
||||
image = gtk_image_new_from_stock (menuitems[i].stock_id,
|
||||
GTK_ICON_SIZE_MENU);
|
||||
|
||||
}
|
||||
|
||||
if (image)
|
||||
{
|
||||
mi = gtk_image_menu_item_new_with_mnemonic (menuitems[i].label);
|
||||
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi),
|
||||
image);
|
||||
gtk_widget_show (image);
|
||||
@ -240,16 +234,19 @@ meta_window_menu_show (gulong xwindow,
|
||||
|
||||
md = g_new (MenuData, 1);
|
||||
|
||||
md->window = window;
|
||||
md->frames = frames;
|
||||
md->frame = frame;
|
||||
md->op = menuitems[i].op;
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (mi),
|
||||
"activate",
|
||||
GTK_SIGNAL_FUNC (activate_cb),
|
||||
md);
|
||||
gtk_signal_connect_full (GTK_OBJECT (mi),
|
||||
"activate",
|
||||
GTK_SIGNAL_FUNC (activate_cb),
|
||||
NULL,
|
||||
md,
|
||||
g_free, FALSE, FALSE);
|
||||
}
|
||||
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (frames->menu),
|
||||
mi);
|
||||
|
||||
gtk_widget_show (mi);
|
||||
@ -257,13 +254,14 @@ meta_window_menu_show (gulong xwindow,
|
||||
++i;
|
||||
}
|
||||
|
||||
if (ops & META_MESSAGE_MENU_WORKSPACES)
|
||||
if (ops & META_MENU_OP_WORKSPACES)
|
||||
{
|
||||
n_workspaces = get_num_desktops ();
|
||||
current_workspace = get_current_desktop (window);
|
||||
n_workspaces = meta_core_get_num_workspaces (DefaultScreenOfDisplay (gdk_display));
|
||||
current_workspace = meta_core_get_frame_workspace (gdk_display,
|
||||
frame->xwindow);
|
||||
|
||||
meta_ui_warning ("Creating %d workspace menu current %d\n",
|
||||
n_workspaces, current_workspace);
|
||||
meta_warning ("Creating %d-workspace menu current %d\n",
|
||||
n_workspaces, current_workspace);
|
||||
|
||||
if (n_workspaces > 0)
|
||||
{
|
||||
@ -275,7 +273,7 @@ meta_window_menu_show (gulong xwindow,
|
||||
char *label;
|
||||
MenuData *md;
|
||||
|
||||
if (current_workspace == 0xFFFFFFFF)
|
||||
if (flags & META_FRAME_STUCK)
|
||||
label = g_strdup_printf (_("Only on workspace _%d\n"),
|
||||
i + 1);
|
||||
else
|
||||
@ -286,25 +284,29 @@ meta_window_menu_show (gulong xwindow,
|
||||
|
||||
g_free (label);
|
||||
|
||||
if (current_workspace == i ||
|
||||
insensitive & META_MESSAGE_MENU_WORKSPACES)
|
||||
if (!(flags & META_FRAME_STUCK) &&
|
||||
(current_workspace == i ||
|
||||
insensitive & META_MENU_OP_WORKSPACES))
|
||||
gtk_widget_set_sensitive (mi, FALSE);
|
||||
|
||||
md = g_new (MenuData, 1);
|
||||
|
||||
md->window = window;
|
||||
md->op = META_MESSAGE_MENU_WORKSPACES;
|
||||
md->frames = frames;
|
||||
md->frame = frame;
|
||||
md->op = META_MENU_OP_WORKSPACES;
|
||||
|
||||
g_object_set_data (G_OBJECT (mi),
|
||||
"workspace",
|
||||
GINT_TO_POINTER (i));
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (mi),
|
||||
"activate",
|
||||
GTK_SIGNAL_FUNC (activate_cb),
|
||||
md);
|
||||
gtk_signal_connect_full (GTK_OBJECT (mi),
|
||||
"activate",
|
||||
GTK_SIGNAL_FUNC (activate_cb),
|
||||
NULL,
|
||||
md,
|
||||
g_free, FALSE, FALSE);
|
||||
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu),
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (frames->menu),
|
||||
mi);
|
||||
|
||||
gtk_widget_show (mi);
|
||||
@ -314,16 +316,16 @@ meta_window_menu_show (gulong xwindow,
|
||||
}
|
||||
}
|
||||
else
|
||||
meta_ui_warning ("not creating workspace menu\n");
|
||||
meta_verbose ("not creating workspace menu\n");
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (frames->menu),
|
||||
"selection_done",
|
||||
GTK_SIGNAL_FUNC (menu_closed),
|
||||
frames);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (menu),
|
||||
"destroy",
|
||||
GTK_SIGNAL_FUNC (gtk_widget_destroyed),
|
||||
&menu);
|
||||
|
||||
pt = g_new (GdkPoint, 1);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (menu),
|
||||
g_object_set_data_full (G_OBJECT (frames->menu),
|
||||
"destroy-point",
|
||||
pt,
|
||||
g_free);
|
||||
@ -331,163 +333,82 @@ meta_window_menu_show (gulong xwindow,
|
||||
pt->x = root_x;
|
||||
pt->y = root_y;
|
||||
|
||||
gtk_menu_popup (GTK_MENU (menu),
|
||||
gtk_menu_popup (GTK_MENU (frames->menu),
|
||||
NULL, NULL,
|
||||
popup_position_func, pt,
|
||||
button,
|
||||
timestamp);
|
||||
|
||||
if (!GTK_MENU_SHELL (menu)->have_xgrab)
|
||||
meta_ui_warning ("GtkMenu failed to grab the pointer\n");
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_menu_hide (void)
|
||||
{
|
||||
if (menu)
|
||||
gtk_widget_destroy (menu);
|
||||
}
|
||||
|
||||
static void
|
||||
close_window (GdkWindow *window)
|
||||
{
|
||||
XClientMessageEvent ev;
|
||||
|
||||
ev.type = ClientMessage;
|
||||
ev.window = GDK_WINDOW_XID (window);
|
||||
ev.message_type = gdk_atom_intern ("_NET_CLOSE_WINDOW", FALSE);
|
||||
ev.format = 32;
|
||||
ev.data.l[0] = 0;
|
||||
ev.data.l[1] = 0;
|
||||
|
||||
gdk_error_trap_push ();
|
||||
XSendEvent (gdk_display,
|
||||
gdk_root_window, False,
|
||||
SubstructureNotifyMask | SubstructureRedirectMask,
|
||||
(XEvent*) &ev);
|
||||
gdk_flush ();
|
||||
gdk_error_trap_pop ();
|
||||
}
|
||||
|
||||
static void
|
||||
wmspec_change_state (gboolean add,
|
||||
GdkWindow *window,
|
||||
GdkAtom state1,
|
||||
GdkAtom state2)
|
||||
{
|
||||
XEvent xev;
|
||||
gulong op;
|
||||
|
||||
if (add)
|
||||
op = _NET_WM_STATE_ADD;
|
||||
else
|
||||
op = _NET_WM_STATE_REMOVE;
|
||||
|
||||
xev.xclient.type = ClientMessage;
|
||||
xev.xclient.serial = 0;
|
||||
xev.xclient.send_event = True;
|
||||
xev.xclient.display = gdk_display;
|
||||
xev.xclient.window = GDK_WINDOW_XID (window);
|
||||
xev.xclient.message_type = gdk_atom_intern ("_NET_WM_STATE", FALSE);
|
||||
xev.xclient.format = 32;
|
||||
xev.xclient.data.l[0] = op;
|
||||
xev.xclient.data.l[1] = state1;
|
||||
xev.xclient.data.l[2] = state2;
|
||||
|
||||
XSendEvent (gdk_display, gdk_root_window, False,
|
||||
SubstructureRedirectMask | SubstructureNotifyMask,
|
||||
&xev);
|
||||
}
|
||||
|
||||
static void
|
||||
wmspec_change_desktop (GdkWindow *window,
|
||||
gint desktop)
|
||||
{
|
||||
XEvent xev;
|
||||
|
||||
xev.xclient.type = ClientMessage;
|
||||
xev.xclient.serial = 0;
|
||||
xev.xclient.send_event = True;
|
||||
xev.xclient.display = gdk_display;
|
||||
xev.xclient.window = GDK_WINDOW_XID (window);
|
||||
xev.xclient.message_type = gdk_atom_intern ("_NET_WM_DESKTOP", FALSE);
|
||||
xev.xclient.format = 32;
|
||||
xev.xclient.data.l[0] = desktop;
|
||||
xev.xclient.data.l[1] = 0;
|
||||
xev.xclient.data.l[2] = 0;
|
||||
|
||||
XSendEvent (gdk_display, gdk_root_window, False,
|
||||
SubstructureRedirectMask | SubstructureNotifyMask,
|
||||
&xev);
|
||||
if (!GTK_MENU_SHELL (frames->menu)->have_xgrab)
|
||||
meta_warning ("GtkMenu failed to grab the pointer\n");
|
||||
}
|
||||
|
||||
static void
|
||||
activate_cb (GtkWidget *menuitem, gpointer data)
|
||||
{
|
||||
MenuData *md;
|
||||
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (menuitem));
|
||||
|
||||
md = data;
|
||||
|
||||
switch (md->op)
|
||||
{
|
||||
case META_MESSAGE_MENU_DELETE:
|
||||
close_window (md->window);
|
||||
case META_MENU_OP_DELETE:
|
||||
meta_core_delete (gdk_display,
|
||||
md->frame->xwindow,
|
||||
gtk_get_current_event_time ());
|
||||
break;
|
||||
|
||||
case META_MESSAGE_MENU_MINIMIZE:
|
||||
gdk_window_iconify (md->window);
|
||||
case META_MENU_OP_MINIMIZE:
|
||||
meta_core_minimize (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
case META_MESSAGE_MENU_UNMAXIMIZE:
|
||||
wmspec_change_state (FALSE, md->window,
|
||||
gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE),
|
||||
gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE));
|
||||
case META_MENU_OP_UNMAXIMIZE:
|
||||
meta_core_unmaximize (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
case META_MESSAGE_MENU_MAXIMIZE:
|
||||
wmspec_change_state (TRUE, md->window,
|
||||
gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE),
|
||||
gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE));
|
||||
case META_MENU_OP_MAXIMIZE:
|
||||
meta_core_maximize (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
case META_MESSAGE_MENU_UNSHADE:
|
||||
wmspec_change_state (FALSE, md->window,
|
||||
gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE),
|
||||
0);
|
||||
case META_MENU_OP_UNSHADE:
|
||||
meta_core_unshade (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
case META_MESSAGE_MENU_SHADE:
|
||||
wmspec_change_state (TRUE, md->window,
|
||||
gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE),
|
||||
0);
|
||||
case META_MENU_OP_SHADE:
|
||||
meta_core_shade (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
case META_MESSAGE_MENU_WORKSPACES:
|
||||
case META_MENU_OP_WORKSPACES:
|
||||
{
|
||||
int workspace;
|
||||
|
||||
workspace = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem),
|
||||
"workspace"));
|
||||
|
||||
wmspec_change_desktop (md->window, workspace);
|
||||
meta_core_change_workspace (gdk_display, md->frame->xwindow,
|
||||
workspace);
|
||||
}
|
||||
break;
|
||||
|
||||
case META_MESSAGE_MENU_STICK:
|
||||
wmspec_change_desktop (md->window, 0xFFFFFFFF);
|
||||
case META_MENU_OP_STICK:
|
||||
meta_core_stick (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
case META_MESSAGE_MENU_UNSTICK:
|
||||
wmspec_change_desktop (md->window, get_active_desktop ());
|
||||
case META_MENU_OP_UNSTICK:
|
||||
meta_core_unstick (gdk_display,
|
||||
md->frame->xwindow);
|
||||
break;
|
||||
|
||||
default:
|
||||
meta_ui_warning (G_STRLOC": Unknown window op\n");
|
||||
meta_warning (G_STRLOC": Unknown window op\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (menu)
|
||||
gtk_widget_destroy (menu);
|
||||
g_object_unref (G_OBJECT (md->window));
|
||||
g_free (md);
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ void meta_window_menu_show (MetaFrames *frames,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp);
|
||||
void meta_window_menu_hide (void);
|
||||
|
||||
|
||||
|
||||
|
@ -130,6 +130,8 @@ meta_debug_spew (const char *format, ...)
|
||||
if (no_prefix == 0)
|
||||
fputs ("Window manager: ", out);
|
||||
fputs (str, out);
|
||||
|
||||
fflush (out);
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
@ -155,6 +157,8 @@ meta_verbose (const char *format, ...)
|
||||
if (no_prefix == 0)
|
||||
fputs ("Window manager: ", out);
|
||||
fputs (str, out);
|
||||
|
||||
fflush (out);
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
@ -177,6 +181,8 @@ meta_bug (const char *format, ...)
|
||||
if (no_prefix == 0)
|
||||
fputs ("Bug in window manager: ", out);
|
||||
fputs (str, out);
|
||||
|
||||
fflush (out);
|
||||
|
||||
g_free (str);
|
||||
|
||||
@ -224,6 +230,8 @@ meta_fatal (const char *format, ...)
|
||||
if (no_prefix == 0)
|
||||
fputs ("Window manager: ", out);
|
||||
fputs (str, out);
|
||||
|
||||
fflush (out);
|
||||
|
||||
g_free (str);
|
||||
|
||||
|
@ -49,6 +49,7 @@ void meta_pop_no_msg_prefix (void);
|
||||
/* FIXME */
|
||||
#include <config.h>
|
||||
#define _(x) x
|
||||
#define N_(x) x
|
||||
|
||||
#endif
|
||||
|
||||
|
142
src/window.c
142
src/window.c
@ -1479,7 +1479,9 @@ process_property_notify (MetaWindow *window,
|
||||
meta_warning ("Broken client changed client leader window or SM client ID\n");
|
||||
}
|
||||
else if (event->atom ==
|
||||
window->display->atom_net_wm_window_type)
|
||||
window->display->atom_net_wm_window_type ||
|
||||
/* update_net_wm_type falls back to this */
|
||||
event->atom == window->display->atom_win_layer)
|
||||
{
|
||||
update_net_wm_type (window);
|
||||
}
|
||||
@ -1993,12 +1995,14 @@ update_mwm_hints (MetaWindow *window)
|
||||
|
||||
result = meta_error_trap_pop (window->display);
|
||||
|
||||
if (result != Success)
|
||||
return result;
|
||||
if (result != Success ||
|
||||
type == None)
|
||||
{
|
||||
meta_verbose ("Window %s has no MWM hints\n", window->desc);
|
||||
/* may be Success, unused anyhow */
|
||||
return result;
|
||||
}
|
||||
|
||||
if (type == None)
|
||||
return -1; /* whatever */
|
||||
|
||||
/* We support MWM hints deemed non-stupid */
|
||||
|
||||
meta_verbose ("Window %s has MWM hints\n",
|
||||
@ -2006,14 +2010,20 @@ update_mwm_hints (MetaWindow *window)
|
||||
|
||||
if (hints->flags & MWM_HINTS_DECORATIONS)
|
||||
{
|
||||
meta_verbose ("Window %s sets MWM decorations to 0x%lx\n",
|
||||
meta_verbose ("Window %s sets MWM_HINTS_DECORATIONS 0x%lx\n",
|
||||
window->desc, hints->decorations);
|
||||
|
||||
if (hints->decorations == 0)
|
||||
window->decorated = FALSE;
|
||||
}
|
||||
else
|
||||
meta_verbose ("Decorations flag unset\n");
|
||||
|
||||
if (hints->flags & MWM_HINTS_FUNCTIONS)
|
||||
{
|
||||
meta_verbose ("Window %s sets MWM_HINTS_FUNCTIONS 0x%lx\n",
|
||||
window->desc, hints->functions);
|
||||
|
||||
if ((hints->functions & MWM_FUNC_CLOSE) == 0)
|
||||
{
|
||||
meta_verbose ("Window %s disables close via MWM hints\n",
|
||||
@ -2033,6 +2043,8 @@ update_mwm_hints (MetaWindow *window)
|
||||
window->has_maximize_func = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
meta_verbose ("Functions flag unset\n");
|
||||
|
||||
XFree (hints);
|
||||
|
||||
@ -2241,6 +2253,52 @@ update_transient_for (MetaWindow *window)
|
||||
return meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
get_cardinal (MetaWindow *window,
|
||||
Atom atom,
|
||||
gulong *val)
|
||||
{
|
||||
Atom type;
|
||||
gint format;
|
||||
gulong nitems;
|
||||
gulong bytes_after;
|
||||
gulong *num;
|
||||
int err;
|
||||
|
||||
meta_error_trap_push (window->display);
|
||||
type = None;
|
||||
XGetWindowProperty (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
atom,
|
||||
0, G_MAXLONG,
|
||||
False, XA_CARDINAL, &type, &format, &nitems,
|
||||
&bytes_after, (guchar **)&num);
|
||||
err = meta_error_trap_pop (window->display);
|
||||
if (err != Success)
|
||||
return FALSE;
|
||||
|
||||
if (type != XA_CARDINAL)
|
||||
return FALSE;
|
||||
|
||||
*val = *num;
|
||||
|
||||
XFree (num);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* some legacy cruft */
|
||||
typedef enum
|
||||
{
|
||||
WIN_LAYER_DESKTOP = 0,
|
||||
WIN_LAYER_BELOW = 2,
|
||||
WIN_LAYER_NORMAL = 4,
|
||||
WIN_LAYER_ONTOP = 6,
|
||||
WIN_LAYER_DOCK = 8,
|
||||
WIN_LAYER_ABOVE_DOCK = 10
|
||||
} GnomeWinLayer;
|
||||
|
||||
static int
|
||||
update_net_wm_type (MetaWindow *window)
|
||||
{
|
||||
@ -2262,17 +2320,39 @@ update_net_wm_type (MetaWindow *window)
|
||||
&bytes_after, (guchar **)&atoms);
|
||||
|
||||
result = meta_error_trap_pop (window->display);
|
||||
if (result != Success)
|
||||
if (result != Success ||
|
||||
type != XA_ATOM)
|
||||
{
|
||||
/* Fall back to WIN_LAYER */
|
||||
gulong layer = WIN_LAYER_NORMAL;
|
||||
|
||||
if (get_cardinal (window, window->display->atom_win_layer,
|
||||
&layer))
|
||||
{
|
||||
meta_verbose ("%s falling back to _WIN_LAYER hint, layer %ld\n",
|
||||
window->desc, layer);
|
||||
switch (layer)
|
||||
{
|
||||
case WIN_LAYER_DESKTOP:
|
||||
window->type_atom =
|
||||
window->display->atom_net_wm_window_type_desktop;
|
||||
break;
|
||||
case WIN_LAYER_NORMAL:
|
||||
window->type_atom =
|
||||
window->display->atom_net_wm_window_type_normal;
|
||||
break;
|
||||
case WIN_LAYER_DOCK:
|
||||
window->type_atom =
|
||||
window->display->atom_net_wm_window_type_dock;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
recalc_window_type (window);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (type != XA_ATOM)
|
||||
{
|
||||
recalc_window_type (window);
|
||||
return -1; /* whatever */
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (i < n_atoms)
|
||||
@ -2316,40 +2396,6 @@ update_net_wm_type (MetaWindow *window)
|
||||
return Success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_cardinal (MetaWindow *window,
|
||||
Atom atom,
|
||||
gulong *val)
|
||||
{
|
||||
Atom type;
|
||||
gint format;
|
||||
gulong nitems;
|
||||
gulong bytes_after;
|
||||
gulong *num;
|
||||
int err;
|
||||
|
||||
meta_error_trap_push (window->display);
|
||||
type = None;
|
||||
XGetWindowProperty (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
atom,
|
||||
0, G_MAXLONG,
|
||||
False, XA_CARDINAL, &type, &format, &nitems,
|
||||
&bytes_after, (guchar **)&num);
|
||||
err = meta_error_trap_pop (window->display);
|
||||
if (err != Success)
|
||||
return FALSE;
|
||||
|
||||
if (type != XA_CARDINAL)
|
||||
return FALSE;
|
||||
|
||||
*val = *num;
|
||||
|
||||
XFree (num);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
update_initial_workspace (MetaWindow *window)
|
||||
{
|
||||
|
@ -220,4 +220,6 @@ gboolean meta_window_client_message (MetaWindow *window,
|
||||
XEvent *event);
|
||||
|
||||
int meta_window_set_current_workspace_hint (MetaWindow *window);
|
||||
|
||||
unsigned long meta_window_get_net_wm_desktop (MetaWindow *window);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user