This commit is contained in:
rhp 2001-06-13 00:56:08 +00:00
parent 29c0947f3c
commit e188d3c4f6
6 changed files with 134 additions and 41 deletions

View File

@ -120,7 +120,8 @@ meta_display_open (const char *name)
"_NET_CLIENT_LIST", "_NET_CLIENT_LIST",
"_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"
}; };
Atom atoms[G_N_ELEMENTS(atom_names)]; Atom atoms[G_N_ELEMENTS(atom_names)];
@ -189,6 +190,7 @@ meta_display_open (const char *name)
display->atom_net_client_list_stacking = atoms[29]; display->atom_net_client_list_stacking = atoms[29];
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];
/* 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

@ -78,6 +78,7 @@ struct _MetaDisplay
Atom atom_net_client_list_stacking; Atom atom_net_client_list_stacking;
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;
/* 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

@ -107,14 +107,14 @@ x_error_handler (Display *xdisplay,
XGetErrorText (xdisplay, error->error_code, buf, 63); XGetErrorText (xdisplay, error->error_code, buf, 63);
meta_fatal ("Received an X Window System error without handling it.\n" meta_bug ("Received an X Window System error without handling it.\n"
"The error was '%s'.\n" "The error was '%s'.\n"
" (Details: serial %ld error_code %d request_code %d minor_code %d)\n", " (Details: serial %ld error_code %d request_code %d minor_code %d)\n",
buf, buf,
error->serial, error->serial,
error->error_code, error->error_code,
error->request_code, error->request_code,
error->minor_code); error->minor_code);
} }
else else
{ {

View File

@ -101,15 +101,22 @@ message_queue_func (MetaMessageQueue *mq,
(* uislave->func) (uislave, message, uislave->data); (* uislave->func) (uislave, message, uislave->data);
} }
static void
child_setup (gpointer data)
{
/* data is leaked, putenv doesn't copy it */
putenv (data);
}
static void static void
respawn_child (MetaUISlave *uislave) respawn_child (MetaUISlave *uislave)
{ {
GError *error; GError *error;
const char *uislavedir; const char *uislavedir;
char *argv[] = { NULL, NULL, NULL, NULL, NULL }; char *argv[] = { NULL, NULL, NULL, NULL, NULL };
char *envp[2] = { NULL, NULL };
int child_pid, inpipe, outpipe, errpipe; int child_pid, inpipe, outpipe, errpipe;
char *path; char *path;
char *disp;
if (uislave->no_respawn) if (uislave->no_respawn)
return; return;
@ -121,7 +128,7 @@ respawn_child (MetaUISlave *uislave)
if (uislavedir == NULL) if (uislavedir == NULL)
uislavedir = METACITY_LIBEXECDIR; uislavedir = METACITY_LIBEXECDIR;
envp[0] = g_strconcat ("DISPLAY=", uislave->display_name, NULL); disp = g_strconcat ("DISPLAY=", uislave->display_name, NULL);
path = g_strconcat (uislavedir, "/", "metacity-uislave", NULL); path = g_strconcat (uislavedir, "/", "metacity-uislave", NULL);
#if 0 #if 0
@ -132,16 +139,15 @@ respawn_child (MetaUISlave *uislave)
argv[0] = path; argv[0] = path;
meta_verbose ("Launching UI slave in dir %s display %s\n", meta_verbose ("Launching UI slave in dir %s display %s\n",
uislavedir, envp[0]); uislavedir, disp);
error = NULL; error = NULL;
if (g_spawn_async_with_pipes (NULL, if (g_spawn_async_with_pipes (NULL,
argv, argv,
envp, NULL,
/* flags */ /* flags */
0, 0,
/* setup func, data */ child_setup, disp,
NULL, NULL,
&child_pid, &child_pid,
&inpipe, &outpipe, &errpipe, &inpipe, &outpipe, &errpipe,
&error)) &error))
@ -171,7 +177,7 @@ respawn_child (MetaUISlave *uislave)
g_error_free (error); g_error_free (error);
} }
g_free (envp[0]); g_free (disp);
g_free (path); g_free (path);
} }

View File

@ -52,6 +52,7 @@ static int update_transient_for (MetaWindow *window);
static void update_sm_hints (MetaWindow *window); static void update_sm_hints (MetaWindow *window);
static int update_role (MetaWindow *window); static int update_role (MetaWindow *window);
static int update_net_wm_type (MetaWindow *window); static int update_net_wm_type (MetaWindow *window);
static int update_initial_workspace (MetaWindow *window);
static void recalc_window_type (MetaWindow *window); static void recalc_window_type (MetaWindow *window);
static int set_wm_state (MetaWindow *window, static int set_wm_state (MetaWindow *window,
int state); int state);
@ -82,6 +83,7 @@ meta_window_new (MetaDisplay *display, Window xwindow,
MetaWindow *window; MetaWindow *window;
XWindowAttributes attrs; XWindowAttributes attrs;
GSList *tmp; GSList *tmp;
MetaWorkspace *space;
meta_verbose ("Attempting to manage 0x%lx\n", xwindow); meta_verbose ("Attempting to manage 0x%lx\n", xwindow);
@ -228,7 +230,8 @@ meta_window_new (MetaDisplay *display, Window xwindow,
window->layer = META_LAYER_NORMAL; window->layer = META_LAYER_NORMAL;
window->stack_op = NULL; window->stack_op = NULL;
window->initial_workspace =
meta_workspace_screen_index (window->screen->active_workspace);
meta_display_register_x_window (display, &window->xwindow, window); meta_display_register_x_window (display, &window->xwindow, window);
update_size_hints (window); update_size_hints (window);
@ -242,6 +245,7 @@ meta_window_new (MetaDisplay *display, Window xwindow,
update_sm_hints (window); /* must come after transient_for */ update_sm_hints (window); /* must come after transient_for */
update_role (window); update_role (window);
update_net_wm_type (window); update_net_wm_type (window);
update_initial_workspace (window);
if (window->initially_iconic) if (window->initially_iconic)
{ {
@ -259,7 +263,14 @@ meta_window_new (MetaDisplay *display, Window xwindow,
if (window->decorated) if (window->decorated)
meta_window_ensure_frame (window); meta_window_ensure_frame (window);
meta_workspace_add_window (window->screen->active_workspace, window); space =
meta_display_get_workspace_by_screen_index (window->display,
window->screen,
window->initial_workspace);
if (space == NULL)
space = window->screen->active_workspace;
meta_workspace_add_window (space, window);
/* Put our state back where it should be, /* Put our state back where it should be,
* passing TRUE for is_configure_request, ICCCM says * passing TRUE for is_configure_request, ICCCM says
@ -775,9 +786,14 @@ meta_window_move_resize_internal (MetaWindow *window,
gboolean need_resize_client = FALSE; gboolean need_resize_client = FALSE;
gboolean need_resize_frame = FALSE; gboolean need_resize_frame = FALSE;
meta_verbose ("Move/resize %s to %d,%d %dx%d%s\n", {
window->desc, root_x_nw, root_y_nw, w, h, int oldx, oldy;
is_configure_request ? " (configure request)" : ""); meta_window_get_position (window, &oldx, &oldy);
meta_verbose ("Move/resize %s to %d,%d %dx%d%s from %d,%d %dx%d\n",
window->desc, root_x_nw, root_y_nw, w, h,
is_configure_request ? " (configure request)" : "",
oldx, oldy, window->rect.width, window->rect.height);
}
/* FIXME we're passing old window size to calc_geometry, /* FIXME we're passing old window size to calc_geometry,
* I believe the right fix is to remove window size * I believe the right fix is to remove window size
@ -892,16 +908,25 @@ meta_window_move_resize_internal (MetaWindow *window,
window->frame->bg_pixel = fgeom.background_pixel; window->frame->bg_pixel = fgeom.background_pixel;
} }
/* See ICCCM 4.1.5 for when to send ConfigureNotify */
need_configure_notify = FALSE;
/* If this is a configure request and we change nothing, then we /* If this is a configure request and we change nothing, then we
* must send configure notify. In all cases we must send configure * must send configure notify.
* notify if we don't resize. ICCCM 4.1.5
*/ */
need_configure_notify = if (is_configure_request &&
(!need_resize_client) || !(need_move_client || need_move_frame ||
(is_configure_request && need_resize_client || need_resize_frame ||
!(need_move_client || need_move_frame || window->border_width != 0))
need_resize_client || need_resize_frame || need_configure_notify = TRUE;
window->border_width != 0));
/* We must send configure notify if we move but don't resize, since
* the client window may not get a real event
*/
if ((need_move_client || need_move_frame) &&
!(need_resize_client || need_resize_frame))
need_configure_notify = TRUE;
/* Sync our new size/pos with X as efficiently as possible */ /* Sync our new size/pos with X as efficiently as possible */
@ -921,10 +946,16 @@ meta_window_move_resize_internal (MetaWindow *window,
if (mask != 0) if (mask != 0)
{ {
meta_verbose ("Syncing new geometry to client, border: %s pos: %s size: %s\n", {
mask & CWBorderWidth ? "true" : "false", int newx, newy;
need_move_client ? "true" : "false", meta_window_get_position (window, &newx, &newy);
need_resize_client ? "true" : "false"); meta_verbose ("Syncing new client geometry %d,%d %dx%d, border: %s pos: %s size: %s\n",
newx, newy,
window->rect.width, window->rect.height,
mask & CWBorderWidth ? "true" : "false",
need_move_client ? "true" : "false",
need_resize_client ? "true" : "false");
}
meta_error_trap_push (window->display); meta_error_trap_push (window->display);
XConfigureWindow (window->display->xdisplay, XConfigureWindow (window->display->xdisplay,
@ -1465,9 +1496,6 @@ send_configure_notify (MetaWindow *window)
/* from twm */ /* from twm */
meta_verbose ("Sending synthetic ConfigureNotify to %s\n",
window->desc);
event.type = ConfigureNotify; event.type = ConfigureNotify;
event.xconfigure.display = window->display->xdisplay; event.xconfigure.display = window->display->xdisplay;
event.xconfigure.event = window->xwindow; event.xconfigure.event = window->xwindow;
@ -1492,9 +1520,9 @@ send_configure_notify (MetaWindow *window)
event.xconfigure.width, event.xconfigure.height); event.xconfigure.width, event.xconfigure.height);
meta_error_trap_push (window->display); meta_error_trap_push (window->display);
XSendEvent(window->display->xdisplay, XSendEvent (window->display->xdisplay,
window->xwindow, window->xwindow,
False, StructureNotifyMask, &event); False, StructureNotifyMask, &event);
meta_error_trap_pop (window->display); meta_error_trap_pop (window->display);
} }
@ -2285,6 +2313,59 @@ 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
update_initial_workspace (MetaWindow *window)
{
gulong val = 0;
/* Fall back to old WM spec hint if net_wm_desktop is missing, this
* is just to be nice when restarting from old Sawfish basically,
* should nuke it eventually
*/
if (get_cardinal (window, window->display->atom_net_wm_desktop,
&val))
window->initial_workspace = val;
else if (get_cardinal (window, window->display->atom_win_workspace,
&val))
window->initial_workspace = val;
return Success;
}
static void static void
recalc_window_type (MetaWindow *window) recalc_window_type (MetaWindow *window)
{ {

View File

@ -66,6 +66,9 @@ struct _MetaWindow
Window xgroup_leader; Window xgroup_leader;
Window xclient_leader; Window xclient_leader;
/* Initial workspace property */
int initial_workspace;
/* Whether we're maximized */ /* Whether we're maximized */
guint maximized : 1; guint maximized : 1;