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 "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);
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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
@ -947,15 +961,33 @@ meta_frames_button_press_event (GtkWidget *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));
if (frame == NULL)
return FALSE;
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;

View File

@ -90,6 +90,8 @@ struct _MetaFrames
GHashTable *frames;
GtkWidget *menu;
/* The below is all for grabs */
MetaFrameStatus grab_status;
MetaUIFrame *grab_frame;
@ -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

View File

@ -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)
static void
menu_closed (GtkMenu *menu,
gpointer data)
{
Atom type;
gint format;
gulong nitems;
gulong bytes_after;
gulong *num;
int result;
MetaFrames *frames;
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);
frames = META_FRAMES (data);
if (type != XA_CARDINAL)
return 0;
meta_frames_notify_menu_hide (frames);
result = *num;
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;
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);
window = gdk_xid_table_lookup (xwindow);
if (window)
g_object_ref (G_OBJECT (window));
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;
}
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;
GtkWidget *image;
GdkPixmap *pix;
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,
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 (menu),
"destroy",
GTK_SIGNAL_FUNC (gtk_widget_destroyed),
&menu);
gtk_signal_connect (GTK_OBJECT (frames->menu),
"selection_done",
GTK_SIGNAL_FUNC (menu_closed),
frames);
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,94 +333,14 @@ 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
@ -426,68 +348,67 @@ 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);
}

View File

@ -31,7 +31,6 @@ void meta_window_menu_show (MetaFrames *frames,
int root_y,
int button,
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 (str, out);
fflush (out);
g_free (str);
}
@ -156,6 +158,8 @@ meta_verbose (const char *format, ...)
fputs ("Window manager: ", out);
fputs (str, out);
fflush (out);
g_free (str);
}
@ -178,6 +182,8 @@ meta_bug (const char *format, ...)
fputs ("Bug in window manager: ", out);
fputs (str, out);
fflush (out);
g_free (str);
/* stop us in a debugger */
@ -225,6 +231,8 @@ meta_fatal (const char *format, ...)
fputs ("Window manager: ", out);
fputs (str, out);
fflush (out);
g_free (str);
meta_exit (META_EXIT_ERROR);

View File

@ -49,6 +49,7 @@ void meta_pop_no_msg_prefix (void);
/* FIXME */
#include <config.h>
#define _(x) x
#define N_(x) x
#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");
}
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,11 +1995,13 @@ update_mwm_hints (MetaWindow *window)
result = meta_error_trap_pop (window->display);
if (result != Success)
return result;
if (type == None)
return -1; /* whatever */
if (result != Success ||
type == None)
{
meta_verbose ("Window %s has no MWM hints\n", window->desc);
/* may be Success, unused anyhow */
return result;
}
/* We support MWM hints deemed non-stupid */
@ -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,18 +2320,40 @@ 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)
{

View File

@ -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