summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core.c122
-rw-r--r--src/core.h6
-rw-r--r--src/display.c6
-rw-r--r--src/display.h1
-rw-r--r--src/errors.c1
-rw-r--r--src/frames.c40
-rw-r--r--src/frames.h8
-rw-r--r--src/menu.c437
-rw-r--r--src/menu.h1
-rw-r--r--src/util.c8
-rw-r--r--src/util.h1
-rw-r--r--src/window.c142
-rw-r--r--src/window.h2
13 files changed, 458 insertions, 317 deletions
diff --git a/src/core.c b/src/core.c
index 72acfa1..330dfef 100644
--- a/src/core.c
+++ b/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);
+}
+
+
diff --git a/src/core.h b/src/core.h
index 97cdfc5..bf6bcdc 100644
--- a/src/core.h
+++ b/src/core.h
@@ -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);
diff --git a/src/display.c b/src/display.c
index b71b482..0cb399f 100644
--- a/src/display.c
+++ b/src/display.c
@@ -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
diff --git a/src/display.h b/src/display.h
index c7dadd6..6f2b24d 100644
--- a/src/display.h
+++ b/src/display.h
@@ -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
diff --git a/src/errors.c b/src/errors.c
index 85b678f..b3dad83 100644
--- a/src/errors.c
+++ b/src/errors.c
@@ -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 */
diff --git a/src/frames.c b/src/frames.c
index 12a6df8..1b0f37e 100644
--- a/src/frames.c
+++ b/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;
diff --git a/src/frames.h b/src/frames.h
index b81c64a..d79c305 100644
--- a/src/frames.h
+++ b/src/frames.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
diff --git a/src/menu.c b/src/menu.c
index c8b51fc..e6cb010 100644
--- a/src/menu.c
+++ b/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);
-
- if (type != XA_CARDINAL)
- return 0;
-
- 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);
+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 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;
+
+ flags = meta_core_get_frame_flags (gdk_display, frame->xwindow);
- if (menu)
- gtk_widget_destroy (menu);
+ 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
+ ops |= META_MENU_OP_SHADE;
- window = gdk_xid_table_lookup (xwindow);
- if (window)
- g_object_ref (G_OBJECT (window));
+ if (flags & META_FRAME_STUCK)
+ ops |= META_MENU_OP_UNSTICK;
else
- window = gdk_window_foreign_new (xwindow);
+ ops |= META_MENU_OP_STICK;
+
+ ops |= (META_MENU_OP_DELETE | META_MENU_OP_WORKSPACES | META_MENU_OP_MINIMIZE);
- /* X error creating the foreign window means NULL here */
- if (window == NULL)
- return;
+ if (!(flags & META_FRAME_ALLOWS_MINIMIZE))
+ insensitive |= META_MENU_OP_MINIMIZE;
- menu = gtk_menu_new ();
+ 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_menu_shell_append (GTK_MENU_SHELL (menu),
+ 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 (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);
}
diff --git a/src/menu.h b/src/menu.h
index de08979..30a096f 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -31,7 +31,6 @@ void meta_window_menu_show (MetaFrames *frames,
int root_y,
int button,
guint32 timestamp);
-void meta_window_menu_hide (void);
diff --git a/src/util.c b/src/util.c
index 0da9a82..4150a8a 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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);
diff --git a/src/util.h b/src/util.h
index 904a789..8892730 100644
--- a/src/util.h
+++ b/src/util.h
@@ -49,6 +49,7 @@ void meta_pop_no_msg_prefix (void);
/* FIXME */
#include <config.h>
#define _(x) x
+#define N_(x) x
#endif
diff --git a/src/window.c b/src/window.c
index f060591..49541f1 100644
--- a/src/window.c
+++ b/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)
{
diff --git a/src/window.h b/src/window.h
index f8149fe..03dacb0 100644
--- a/src/window.h
+++ b/src/window.h
@@ -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