This commit is contained in:
rhp 2001-06-21 06:08:35 +00:00
parent 5611d75a11
commit 9e9ffdca42
13 changed files with 457 additions and 316 deletions

View File

@ -21,6 +21,7 @@
#include "core.h" #include "core.h"
#include "frame.h" #include "frame.h"
#include "workspace.h"
void void
meta_core_get_frame_size (Display *xdisplay, meta_core_get_frame_size (Display *xdisplay,
@ -234,3 +235,124 @@ meta_core_delete (Display *xdisplay,
meta_window_delete (window, timestamp); 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);
}

View File

@ -85,10 +85,8 @@ void meta_core_change_workspace (Display *xdisplay,
int new_workspace); int new_workspace);
int meta_core_get_num_workspaces (Display *xdisplay, int meta_core_get_num_workspaces (Screen *xscreen);
Screen *xscreen); int meta_core_get_active_workspace (Screen *xscreen);
int meta_core_get_active_workspace (Display *xdisplay,
Screen *xscreen);
int meta_core_get_frame_workspace (Display *xdisplay, int meta_core_get_frame_workspace (Display *xdisplay,
Window frame_xwindow); Window frame_xwindow);

View File

@ -99,7 +99,7 @@ meta_display_open (const char *name)
"WM_STATE", "WM_STATE",
"_NET_CLOSE_WINDOW", "_NET_CLOSE_WINDOW",
"_NET_WM_STATE", "_NET_WM_STATE",
"MOTIF_WM_HINTS", "_MOTIF_WM_HINTS",
"_NET_WM_STATE_SHADED", "_NET_WM_STATE_SHADED",
"_NET_WM_STATE_MAXIMIZED_HORZ", "_NET_WM_STATE_MAXIMIZED_HORZ",
"_NET_WM_STATE_MAXIMIZED_VERT", "_NET_WM_STATE_MAXIMIZED_VERT",
@ -124,7 +124,8 @@ meta_display_open (const char *name)
"_NET_CLIENT_LIST_STACKING", "_NET_CLIENT_LIST_STACKING",
"_NET_WM_STATE_SKIP_TASKBAR", "_NET_WM_STATE_SKIP_TASKBAR",
"_NET_WM_STATE_SKIP_PAGER", "_NET_WM_STATE_SKIP_PAGER",
"_WIN_WORKSPACE" "_WIN_WORKSPACE",
"_WIN_LAYER"
}; };
Atom atoms[G_N_ELEMENTS(atom_names)]; 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_taskbar = atoms[30];
display->atom_net_wm_state_skip_pager = atoms[31]; display->atom_net_wm_state_skip_pager = atoms[31];
display->atom_win_workspace = atoms[32]; display->atom_win_workspace = atoms[32];
display->atom_win_layer = atoms[33];
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK, /* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
* created in screen_new * created in screen_new

View File

@ -89,6 +89,7 @@ struct _MetaDisplay
Atom atom_net_wm_state_skip_taskbar; Atom atom_net_wm_state_skip_taskbar;
Atom atom_net_wm_state_skip_pager; Atom atom_net_wm_state_skip_pager;
Atom atom_win_workspace; Atom atom_win_workspace;
Atom atom_win_layer;
/* This is the actual window from focus events, /* This is the actual window from focus events,
* not the one we last set * not the one we last set

View File

@ -64,6 +64,7 @@ meta_error_trap_pop (MetaDisplay *display)
ErrorTrap *et; ErrorTrap *et;
GSList *next; GSList *next;
XSync (display->xdisplay, False);
return gdk_error_trap_pop (); return gdk_error_trap_pop ();
/* below here is old method */ /* below here is old method */

View File

@ -359,6 +359,20 @@ queue_recalc_func (gpointer key, gpointer value, gpointer data)
gdk_window_invalidate_rect (frame->window, NULL, FALSE); gdk_window_invalidate_rect (frame->window, NULL, FALSE);
meta_core_queue_frame_resize (gdk_display, meta_core_queue_frame_resize (gdk_display,
frame->xwindow); 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 static void
@ -947,15 +961,33 @@ meta_frames_button_press_event (GtkWidget *widget,
frames = META_FRAMES (widget); 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)); frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
if (frame == NULL) if (frame == NULL)
return FALSE; return FALSE;
control = get_control (frames, frame, event->x, event->y); 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) if (event->button == 1)
meta_core_user_raise (gdk_display, frame->xwindow); 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 && else if (control == META_FRAME_CONTROL_RESIZE_SE &&
event->button == 1) event->button == 1)
{ {
int w, h; int w, h;

View File

@ -90,6 +90,8 @@ struct _MetaFrames
GHashTable *frames; GHashTable *frames;
GtkWidget *menu;
/* The below is all for grabs */ /* The below is all for grabs */
MetaFrameStatus grab_status; MetaFrameStatus grab_status;
MetaUIFrame *grab_frame; MetaUIFrame *grab_frame;
@ -130,4 +132,10 @@ void meta_frames_reset_bg (MetaFrames *frames,
void meta_frames_queue_draw (MetaFrames *frames, void meta_frames_queue_draw (MetaFrames *frames,
Window xwindow); 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 #endif

View File

@ -21,6 +21,8 @@
#include "menu.h" #include "menu.h"
#include "main.h" #include "main.h"
#include "util.h"
#include "core.h"
typedef struct _MenuItem MenuItem; typedef struct _MenuItem MenuItem;
typedef struct _MenuData MenuData; typedef struct _MenuData MenuData;
@ -48,23 +50,23 @@ struct _MenuItem
struct _MenuData struct _MenuData
{ {
GdkWindow *window; MetaFrames *frames;
MetaMessageWindowMenuOps op; MetaUIFrame *frame;
MetaMenuOp op;
}; };
static void activate_cb (GtkWidget *menuitem, gpointer data); static void activate_cb (GtkWidget *menuitem, gpointer data);
static GtkWidget *menu = NULL;
static MenuItem menuitems[] = { static MenuItem menuitems[] = {
{ META_MESSAGE_MENU_DELETE, GTK_STOCK_CLOSE, N_("_Close") }, { META_MENU_OP_DELETE, NULL, N_("_Close") },
{ META_MESSAGE_MENU_MINIMIZE, NULL, N_("_Minimize") }, { META_MENU_OP_MINIMIZE, NULL, N_("_Minimize") },
{ META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Ma_ximize") }, { META_MENU_OP_MAXIMIZE, NULL, N_("Ma_ximize") },
{ META_MESSAGE_MENU_UNMAXIMIZE, NULL, N_("_Unmaximize") }, { META_MENU_OP_UNMAXIMIZE, NULL, N_("_Unmaximize") },
{ META_MESSAGE_MENU_SHADE, NULL, N_("_Shade") }, { META_MENU_OP_SHADE, NULL, N_("_Shade") },
{ META_MESSAGE_MENU_UNSHADE, NULL, N_("U_nshade") }, { META_MENU_OP_UNSHADE, NULL, N_("U_nshade") },
{ 0, NULL, NULL }, /* separator */ { 0, NULL, NULL }, /* separator */
{ META_MESSAGE_MENU_STICK, NULL, N_("Put on _All Workspaces") }, { META_MENU_OP_STICK, NULL, N_("Put on _All Workspaces") },
{ META_MESSAGE_MENU_UNSTICK, NULL, N_("Only on _This Workspace") } { META_MENU_OP_UNSTICK, NULL, N_("Only on _This Workspace") }
}; };
static void static void
@ -89,121 +91,71 @@ popup_position_func (GtkMenu *menu,
*y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height)); *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
} }
static gint static void
get_num_desktops (void) menu_closed (GtkMenu *menu,
gpointer data)
{ {
Atom type; MetaFrames *frames;
gint format;
gulong nitems;
gulong bytes_after;
gulong *num;
int result;
XGetWindowProperty (gdk_display, gdk_root_window, frames = META_FRAMES (data);
gdk_atom_intern ("_NET_NUMBER_OF_DESKTOPS", FALSE),
0, G_MAXLONG,
False, XA_CARDINAL, &type, &format, &nitems,
&bytes_after, (guchar **)&num);
if (type != XA_CARDINAL) meta_frames_notify_menu_hide (frames);
return 0;
result = *num; gtk_widget_destroy (frames->menu);
frames->menu = NULL;
XFree (num);
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;
} }
void void
meta_window_menu_show (gulong xwindow, meta_window_menu_show (MetaFrames *frames,
int root_x, int root_y, MetaUIFrame *frame,
int button, int root_x,
MetaMessageWindowMenuOps ops, int root_y,
MetaMessageWindowMenuOps insensitive, int button,
guint32 timestamp) guint32 timestamp)
{ {
int i; int i;
GdkWindow *window;
GdkPoint *pt; GdkPoint *pt;
int n_workspaces; int n_workspaces;
int current_workspace; int current_workspace;
MetaMenuOp ops;
MetaMenuOp insensitive;
MetaFrameFlags flags;
if (menu) flags = meta_core_get_frame_flags (gdk_display, frame->xwindow);
gtk_widget_destroy (menu);
window = gdk_xid_table_lookup (xwindow); ops = 0;
if (window) insensitive = 0;
g_object_ref (G_OBJECT (window));
if (flags & META_FRAME_ALLOWS_MAXIMIZE)
{
if (flags & META_FRAME_MAXIMIZED)
ops |= META_MENU_OP_UNMAXIMIZE;
else
ops |= META_MENU_OP_MAXIMIZE;
}
if (flags & META_FRAME_SHADED)
ops |= META_MENU_OP_UNSHADE;
else else
window = gdk_window_foreign_new (xwindow); ops |= META_MENU_OP_SHADE;
/* X error creating the foreign window means NULL here */ if (flags & META_FRAME_STUCK)
if (window == NULL) ops |= META_MENU_OP_UNSTICK;
return; 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; i = 0;
while (i < G_N_ELEMENTS (menuitems)) while (i < G_N_ELEMENTS (menuitems))
@ -219,13 +171,55 @@ meta_window_menu_show (gulong xwindow,
} }
else else
{ {
if (menuitems[i].stock_id) GtkWidget *image;
{ GdkPixmap *pix;
GtkWidget *image; GdkBitmap *mask;
mi = gtk_image_menu_item_new_with_mnemonic (menuitems[i].label); image = NULL;
pix = NULL;
mask = NULL;
switch (menuitems[i].op)
{
case META_MENU_OP_MAXIMIZE:
meta_frames_get_pixmap_for_control (frames,
META_FRAME_CONTROL_MAXIMIZE,
&pix, &mask);
break;
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, image = gtk_image_new_from_stock (menuitems[i].stock_id,
GTK_ICON_SIZE_MENU); 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), gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi),
image); image);
gtk_widget_show (image); gtk_widget_show (image);
@ -240,16 +234,19 @@ meta_window_menu_show (gulong xwindow,
md = g_new (MenuData, 1); md = g_new (MenuData, 1);
md->window = window; md->frames = frames;
md->frame = frame;
md->op = menuitems[i].op; md->op = menuitems[i].op;
gtk_signal_connect (GTK_OBJECT (mi), gtk_signal_connect_full (GTK_OBJECT (mi),
"activate", "activate",
GTK_SIGNAL_FUNC (activate_cb), GTK_SIGNAL_FUNC (activate_cb),
md); NULL,
md,
g_free, FALSE, FALSE);
} }
gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_menu_shell_append (GTK_MENU_SHELL (frames->menu),
mi); mi);
gtk_widget_show (mi); gtk_widget_show (mi);
@ -257,13 +254,14 @@ meta_window_menu_show (gulong xwindow,
++i; ++i;
} }
if (ops & META_MESSAGE_MENU_WORKSPACES) if (ops & META_MENU_OP_WORKSPACES)
{ {
n_workspaces = get_num_desktops (); n_workspaces = meta_core_get_num_workspaces (DefaultScreenOfDisplay (gdk_display));
current_workspace = get_current_desktop (window); current_workspace = meta_core_get_frame_workspace (gdk_display,
frame->xwindow);
meta_ui_warning ("Creating %d workspace menu current %d\n", meta_warning ("Creating %d-workspace menu current %d\n",
n_workspaces, current_workspace); n_workspaces, current_workspace);
if (n_workspaces > 0) if (n_workspaces > 0)
{ {
@ -275,7 +273,7 @@ meta_window_menu_show (gulong xwindow,
char *label; char *label;
MenuData *md; MenuData *md;
if (current_workspace == 0xFFFFFFFF) if (flags & META_FRAME_STUCK)
label = g_strdup_printf (_("Only on workspace _%d\n"), label = g_strdup_printf (_("Only on workspace _%d\n"),
i + 1); i + 1);
else else
@ -286,25 +284,29 @@ meta_window_menu_show (gulong xwindow,
g_free (label); g_free (label);
if (current_workspace == i || if (!(flags & META_FRAME_STUCK) &&
insensitive & META_MESSAGE_MENU_WORKSPACES) (current_workspace == i ||
insensitive & META_MENU_OP_WORKSPACES))
gtk_widget_set_sensitive (mi, FALSE); gtk_widget_set_sensitive (mi, FALSE);
md = g_new (MenuData, 1); md = g_new (MenuData, 1);
md->window = window; md->frames = frames;
md->op = META_MESSAGE_MENU_WORKSPACES; md->frame = frame;
md->op = META_MENU_OP_WORKSPACES;
g_object_set_data (G_OBJECT (mi), g_object_set_data (G_OBJECT (mi),
"workspace", "workspace",
GINT_TO_POINTER (i)); GINT_TO_POINTER (i));
gtk_signal_connect (GTK_OBJECT (mi), gtk_signal_connect_full (GTK_OBJECT (mi),
"activate", "activate",
GTK_SIGNAL_FUNC (activate_cb), GTK_SIGNAL_FUNC (activate_cb),
md); NULL,
md,
g_free, FALSE, FALSE);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_menu_shell_append (GTK_MENU_SHELL (frames->menu),
mi); mi);
gtk_widget_show (mi); gtk_widget_show (mi);
@ -314,16 +316,16 @@ meta_window_menu_show (gulong xwindow,
} }
} }
else else
meta_ui_warning ("not creating workspace menu\n"); meta_verbose ("not creating workspace menu\n");
gtk_signal_connect (GTK_OBJECT (menu), gtk_signal_connect (GTK_OBJECT (frames->menu),
"destroy", "selection_done",
GTK_SIGNAL_FUNC (gtk_widget_destroyed), GTK_SIGNAL_FUNC (menu_closed),
&menu); frames);
pt = g_new (GdkPoint, 1); pt = g_new (GdkPoint, 1);
g_object_set_data_full (G_OBJECT (menu), g_object_set_data_full (G_OBJECT (frames->menu),
"destroy-point", "destroy-point",
pt, pt,
g_free); g_free);
@ -331,94 +333,14 @@ meta_window_menu_show (gulong xwindow,
pt->x = root_x; pt->x = root_x;
pt->y = root_y; pt->y = root_y;
gtk_menu_popup (GTK_MENU (menu), gtk_menu_popup (GTK_MENU (frames->menu),
NULL, NULL, NULL, NULL,
popup_position_func, pt, popup_position_func, pt,
button, button,
timestamp); timestamp);
if (!GTK_MENU_SHELL (menu)->have_xgrab) if (!GTK_MENU_SHELL (frames->menu)->have_xgrab)
meta_ui_warning ("GtkMenu failed to grab the pointer\n"); meta_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);
} }
static void static void
@ -426,68 +348,67 @@ activate_cb (GtkWidget *menuitem, gpointer data)
{ {
MenuData *md; MenuData *md;
g_return_if_fail (GTK_IS_WIDGET (menuitem));
md = data; md = data;
switch (md->op) switch (md->op)
{ {
case META_MESSAGE_MENU_DELETE: case META_MENU_OP_DELETE:
close_window (md->window); meta_core_delete (gdk_display,
md->frame->xwindow,
gtk_get_current_event_time ());
break; break;
case META_MESSAGE_MENU_MINIMIZE: case META_MENU_OP_MINIMIZE:
gdk_window_iconify (md->window); meta_core_minimize (gdk_display,
md->frame->xwindow);
break; break;
case META_MESSAGE_MENU_UNMAXIMIZE: case META_MENU_OP_UNMAXIMIZE:
wmspec_change_state (FALSE, md->window, meta_core_unmaximize (gdk_display,
gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE), md->frame->xwindow);
gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE));
break; break;
case META_MESSAGE_MENU_MAXIMIZE: case META_MENU_OP_MAXIMIZE:
wmspec_change_state (TRUE, md->window, meta_core_maximize (gdk_display,
gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE), md->frame->xwindow);
gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE));
break; break;
case META_MESSAGE_MENU_UNSHADE: case META_MENU_OP_UNSHADE:
wmspec_change_state (FALSE, md->window, meta_core_unshade (gdk_display,
gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE), md->frame->xwindow);
0);
break; break;
case META_MESSAGE_MENU_SHADE: case META_MENU_OP_SHADE:
wmspec_change_state (TRUE, md->window, meta_core_shade (gdk_display,
gdk_atom_intern ("_NET_WM_STATE_SHADED", FALSE), md->frame->xwindow);
0);
break; break;
case META_MESSAGE_MENU_WORKSPACES: case META_MENU_OP_WORKSPACES:
{ {
int workspace; int workspace;
workspace = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), workspace = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem),
"workspace")); "workspace"));
wmspec_change_desktop (md->window, workspace); meta_core_change_workspace (gdk_display, md->frame->xwindow,
workspace);
} }
break; break;
case META_MESSAGE_MENU_STICK: case META_MENU_OP_STICK:
wmspec_change_desktop (md->window, 0xFFFFFFFF); meta_core_stick (gdk_display,
md->frame->xwindow);
break; break;
case META_MESSAGE_MENU_UNSTICK: case META_MENU_OP_UNSTICK:
wmspec_change_desktop (md->window, get_active_desktop ()); meta_core_unstick (gdk_display,
md->frame->xwindow);
break; break;
default: default:
meta_ui_warning (G_STRLOC": Unknown window op\n"); meta_warning (G_STRLOC": Unknown window op\n");
break; break;
} }
if (menu)
gtk_widget_destroy (menu);
g_object_unref (G_OBJECT (md->window));
g_free (md);
} }

View File

@ -31,7 +31,6 @@ void meta_window_menu_show (MetaFrames *frames,
int root_y, int root_y,
int button, int button,
guint32 timestamp); guint32 timestamp);
void meta_window_menu_hide (void);

View File

@ -131,6 +131,8 @@ meta_debug_spew (const char *format, ...)
fputs ("Window manager: ", out); fputs ("Window manager: ", out);
fputs (str, out); fputs (str, out);
fflush (out);
g_free (str); g_free (str);
} }
@ -156,6 +158,8 @@ meta_verbose (const char *format, ...)
fputs ("Window manager: ", out); fputs ("Window manager: ", out);
fputs (str, out); fputs (str, out);
fflush (out);
g_free (str); g_free (str);
} }
@ -178,6 +182,8 @@ meta_bug (const char *format, ...)
fputs ("Bug in window manager: ", out); fputs ("Bug in window manager: ", out);
fputs (str, out); fputs (str, out);
fflush (out);
g_free (str); g_free (str);
/* stop us in a debugger */ /* stop us in a debugger */
@ -225,6 +231,8 @@ meta_fatal (const char *format, ...)
fputs ("Window manager: ", out); fputs ("Window manager: ", out);
fputs (str, out); fputs (str, out);
fflush (out);
g_free (str); g_free (str);
meta_exit (META_EXIT_ERROR); meta_exit (META_EXIT_ERROR);

View File

@ -49,6 +49,7 @@ void meta_pop_no_msg_prefix (void);
/* FIXME */ /* FIXME */
#include <config.h> #include <config.h>
#define _(x) x #define _(x) x
#define N_(x) x
#endif #endif

View File

@ -1479,7 +1479,9 @@ process_property_notify (MetaWindow *window,
meta_warning ("Broken client changed client leader window or SM client ID\n"); meta_warning ("Broken client changed client leader window or SM client ID\n");
} }
else if (event->atom == 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); update_net_wm_type (window);
} }
@ -1993,11 +1995,13 @@ update_mwm_hints (MetaWindow *window)
result = meta_error_trap_pop (window->display); result = meta_error_trap_pop (window->display);
if (result != Success) if (result != Success ||
return result; type == None)
{
if (type == None) meta_verbose ("Window %s has no MWM hints\n", window->desc);
return -1; /* whatever */ /* may be Success, unused anyhow */
return result;
}
/* We support MWM hints deemed non-stupid */ /* We support MWM hints deemed non-stupid */
@ -2006,14 +2010,20 @@ update_mwm_hints (MetaWindow *window)
if (hints->flags & MWM_HINTS_DECORATIONS) 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); window->desc, hints->decorations);
if (hints->decorations == 0) if (hints->decorations == 0)
window->decorated = FALSE; window->decorated = FALSE;
} }
else
meta_verbose ("Decorations flag unset\n");
if (hints->flags & MWM_HINTS_FUNCTIONS) 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) if ((hints->functions & MWM_FUNC_CLOSE) == 0)
{ {
meta_verbose ("Window %s disables close via MWM hints\n", meta_verbose ("Window %s disables close via MWM hints\n",
@ -2033,6 +2043,8 @@ update_mwm_hints (MetaWindow *window)
window->has_maximize_func = FALSE; window->has_maximize_func = FALSE;
} }
} }
else
meta_verbose ("Functions flag unset\n");
XFree (hints); XFree (hints);
@ -2241,6 +2253,52 @@ update_transient_for (MetaWindow *window)
return meta_error_trap_pop (window->display); 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 static int
update_net_wm_type (MetaWindow *window) update_net_wm_type (MetaWindow *window)
{ {
@ -2262,18 +2320,40 @@ update_net_wm_type (MetaWindow *window)
&bytes_after, (guchar **)&atoms); &bytes_after, (guchar **)&atoms);
result = meta_error_trap_pop (window->display); 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); recalc_window_type (window);
return result; return result;
} }
if (type != XA_ATOM)
{
recalc_window_type (window);
return -1; /* whatever */
}
i = 0; i = 0;
while (i < n_atoms) while (i < n_atoms)
{ {
@ -2316,40 +2396,6 @@ update_net_wm_type (MetaWindow *window)
return Success; 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 static int
update_initial_workspace (MetaWindow *window) update_initial_workspace (MetaWindow *window)
{ {

View File

@ -220,4 +220,6 @@ gboolean meta_window_client_message (MetaWindow *window,
XEvent *event); XEvent *event);
int meta_window_set_current_workspace_hint (MetaWindow *window); int meta_window_set_current_workspace_hint (MetaWindow *window);
unsigned long meta_window_get_net_wm_desktop (MetaWindow *window);
#endif #endif