mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
...
This commit is contained in:
parent
c533bc838e
commit
146361b6f5
@ -55,6 +55,8 @@ metacity_SOURCES= \
|
|||||||
main.h \
|
main.h \
|
||||||
screen.c \
|
screen.c \
|
||||||
screen.h \
|
screen.h \
|
||||||
|
session.c \
|
||||||
|
session.h \
|
||||||
theme.c \
|
theme.c \
|
||||||
theme.h \
|
theme.h \
|
||||||
uislave.c \
|
uislave.c \
|
||||||
|
@ -86,7 +86,11 @@ meta_display_open (const char *name)
|
|||||||
"_NET_WM_STATE_MAXIMIZED_HORZ",
|
"_NET_WM_STATE_MAXIMIZED_HORZ",
|
||||||
"_NET_WM_STATE_MAXIMIZED_VERT",
|
"_NET_WM_STATE_MAXIMIZED_VERT",
|
||||||
"_NET_WM_DESKTOP",
|
"_NET_WM_DESKTOP",
|
||||||
"_NET_NUMBER_OF_DESKTOPS"
|
"_NET_NUMBER_OF_DESKTOPS",
|
||||||
|
"WM_CHANGE_STATE",
|
||||||
|
"SM_CLIENT_ID",
|
||||||
|
"WM_CLIENT_LEADER",
|
||||||
|
"WM_WINDOW_ROLE"
|
||||||
};
|
};
|
||||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||||
|
|
||||||
@ -136,6 +140,10 @@ meta_display_open (const char *name)
|
|||||||
display->atom_net_wm_state_maximized_vert = atoms[10];
|
display->atom_net_wm_state_maximized_vert = atoms[10];
|
||||||
display->atom_net_wm_desktop = atoms[11];
|
display->atom_net_wm_desktop = atoms[11];
|
||||||
display->atom_net_number_of_desktops = atoms[12];
|
display->atom_net_number_of_desktops = atoms[12];
|
||||||
|
display->atom_wm_change_state = atoms[13];
|
||||||
|
display->atom_sm_client_id = atoms[14];
|
||||||
|
display->atom_wm_client_leader = atoms[15];
|
||||||
|
display->atom_wm_window_role = atoms[16];
|
||||||
|
|
||||||
screens = NULL;
|
screens = NULL;
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -175,6 +183,13 @@ meta_display_open (const char *name)
|
|||||||
display->last_button_xwindow = None;
|
display->last_button_xwindow = None;
|
||||||
display->last_button_num = 0;
|
display->last_button_num = 0;
|
||||||
display->is_double_click = FALSE;
|
display->is_double_click = FALSE;
|
||||||
|
|
||||||
|
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK
|
||||||
|
*/
|
||||||
|
display->leader_window =
|
||||||
|
XCreateSimpleWindow (display->xdisplay,
|
||||||
|
((MetaScreen*)display->screens->data)->xroot,
|
||||||
|
-100, -100, 1, 1, 0, 0, 0);
|
||||||
|
|
||||||
/* Now manage all existing windows */
|
/* Now manage all existing windows */
|
||||||
tmp = display->screens;
|
tmp = display->screens;
|
||||||
@ -241,6 +256,8 @@ meta_display_close (MetaDisplay *display)
|
|||||||
* unregister windows
|
* unregister windows
|
||||||
*/
|
*/
|
||||||
g_hash_table_destroy (display->window_ids);
|
g_hash_table_destroy (display->window_ids);
|
||||||
|
|
||||||
|
XDestroyWindow (display->xdisplay, display->leader_window);
|
||||||
|
|
||||||
meta_event_queue_free (display->events);
|
meta_event_queue_free (display->events);
|
||||||
XCloseDisplay (display->xdisplay);
|
XCloseDisplay (display->xdisplay);
|
||||||
|
@ -43,6 +43,8 @@ struct _MetaDisplay
|
|||||||
char *name;
|
char *name;
|
||||||
Display *xdisplay;
|
Display *xdisplay;
|
||||||
|
|
||||||
|
Window leader_window;
|
||||||
|
|
||||||
Atom atom_net_wm_name;
|
Atom atom_net_wm_name;
|
||||||
Atom atom_wm_protocols;
|
Atom atom_wm_protocols;
|
||||||
Atom atom_wm_take_focus;
|
Atom atom_wm_take_focus;
|
||||||
@ -56,6 +58,10 @@ struct _MetaDisplay
|
|||||||
Atom atom_net_wm_state_maximized_vert;
|
Atom atom_net_wm_state_maximized_vert;
|
||||||
Atom atom_net_wm_desktop;
|
Atom atom_net_wm_desktop;
|
||||||
Atom atom_net_number_of_desktops;
|
Atom atom_net_number_of_desktops;
|
||||||
|
Atom atom_wm_change_state;
|
||||||
|
Atom atom_sm_client_id;
|
||||||
|
Atom atom_wm_client_leader;
|
||||||
|
Atom atom_wm_window_role;
|
||||||
|
|
||||||
/* 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
|
||||||
|
229
src/frame.c
229
src/frame.c
@ -79,61 +79,77 @@ meta_frame_init_info (MetaFrame *frame,
|
|||||||
info->current_control_state = META_STATE_PRELIGHT;
|
info->current_control_state = META_STATE_PRELIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
meta_frame_calc_initial_pos (MetaFrame *frame,
|
/* returns values suitable for meta_window_move */
|
||||||
int child_root_x, int child_root_y)
|
void
|
||||||
|
meta_frame_adjust_for_gravity (int win_gravity,
|
||||||
|
int frame_width,
|
||||||
|
int frame_height,
|
||||||
|
MetaFrameGeometry *fgeom,
|
||||||
|
int child_root_x,
|
||||||
|
int child_root_y,
|
||||||
|
int *win_root_x,
|
||||||
|
int *win_root_y)
|
||||||
{
|
{
|
||||||
MetaWindow *window;
|
int x, y;
|
||||||
|
|
||||||
|
/* NW coordinate of the frame. We should just
|
||||||
|
* compute NW coordinate to return from the start,
|
||||||
|
* but I wrote it this way first and am now lazy
|
||||||
|
*/
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
|
||||||
window = frame->window;
|
switch (win_gravity)
|
||||||
|
|
||||||
switch (window->size_hints.win_gravity)
|
|
||||||
{
|
{
|
||||||
case NorthWestGravity:
|
case NorthWestGravity:
|
||||||
frame->rect.x = child_root_x;
|
x = child_root_x;
|
||||||
frame->rect.y = child_root_y;
|
y = child_root_y;
|
||||||
break;
|
break;
|
||||||
case NorthGravity:
|
case NorthGravity:
|
||||||
frame->rect.x = child_root_x - frame->rect.width / 2;
|
x = child_root_x - frame_width / 2;
|
||||||
frame->rect.y = child_root_y;
|
y = child_root_y;
|
||||||
break;
|
break;
|
||||||
case NorthEastGravity:
|
case NorthEastGravity:
|
||||||
frame->rect.x = child_root_x - frame->rect.width;
|
x = child_root_x - frame_width;
|
||||||
frame->rect.y = child_root_y;
|
y = child_root_y;
|
||||||
break;
|
break;
|
||||||
case WestGravity:
|
case WestGravity:
|
||||||
frame->rect.x = child_root_x;
|
x = child_root_x;
|
||||||
frame->rect.y = child_root_y - frame->rect.height / 2;
|
y = child_root_y - frame_height / 2;
|
||||||
break;
|
break;
|
||||||
case CenterGravity:
|
case CenterGravity:
|
||||||
frame->rect.x = child_root_x - frame->rect.width / 2;
|
x = child_root_x - frame_width / 2;
|
||||||
frame->rect.y = child_root_y - frame->rect.height / 2;
|
y = child_root_y - frame_height / 2;
|
||||||
break;
|
break;
|
||||||
case EastGravity:
|
case EastGravity:
|
||||||
frame->rect.x = child_root_x - frame->rect.width;
|
x = child_root_x - frame_width;
|
||||||
frame->rect.y = child_root_y - frame->rect.height / 2;
|
y = child_root_y - frame_height / 2;
|
||||||
break;
|
break;
|
||||||
case SouthWestGravity:
|
case SouthWestGravity:
|
||||||
frame->rect.x = child_root_x;
|
x = child_root_x;
|
||||||
frame->rect.y = child_root_y - frame->rect.height;
|
y = child_root_y - frame_height;
|
||||||
break;
|
break;
|
||||||
case SouthGravity:
|
case SouthGravity:
|
||||||
frame->rect.x = child_root_x - frame->rect.width / 2;
|
x = child_root_x - frame_width / 2;
|
||||||
frame->rect.y = child_root_y - frame->rect.height;
|
y = child_root_y - frame_height;
|
||||||
break;
|
break;
|
||||||
case SouthEastGravity:
|
case SouthEastGravity:
|
||||||
frame->rect.x = child_root_x - frame->rect.width;
|
x = child_root_x - frame_width;
|
||||||
frame->rect.y = child_root_y - frame->rect.height;
|
y = child_root_y - frame_height;
|
||||||
break;
|
break;
|
||||||
case StaticGravity:
|
case StaticGravity:
|
||||||
default:
|
default:
|
||||||
frame->rect.x = child_root_x - frame->child_x;
|
x = child_root_x - fgeom->left_width;
|
||||||
frame->rect.y = child_root_y - frame->child_y;
|
y = child_root_y - fgeom->top_height;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*win_root_x = x + fgeom->left_width;
|
||||||
|
*win_root_y = y + fgeom->top_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
meta_frame_calc_geometry (MetaFrame *frame,
|
meta_frame_calc_geometry (MetaFrame *frame,
|
||||||
int child_width, int child_height,
|
int child_width, int child_height,
|
||||||
MetaFrameGeometry *geomp)
|
MetaFrameGeometry *geomp)
|
||||||
@ -143,20 +159,22 @@ meta_frame_calc_geometry (MetaFrame *frame,
|
|||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
|
|
||||||
/* Remember this is called from the constructor
|
/* Remember this is called from the constructor
|
||||||
* pre-window-creation.
|
* pre-X-window-creation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
window = frame->window;
|
window = frame->window;
|
||||||
|
|
||||||
frame->rect.width = child_width;
|
/* frame->rect isn't useful yet */
|
||||||
|
|
||||||
if (window->shaded)
|
|
||||||
frame->rect.height = 0;
|
|
||||||
else
|
|
||||||
frame->rect.height = child_height;
|
|
||||||
|
|
||||||
meta_frame_init_info (frame, &info);
|
meta_frame_init_info (frame, &info);
|
||||||
|
|
||||||
|
/* these were from frame->rect so fix them up */
|
||||||
|
info.width = child_width;
|
||||||
|
if (window->shaded)
|
||||||
|
info.height = 0;
|
||||||
|
else
|
||||||
|
info.height = child_height;
|
||||||
|
|
||||||
if (!frame->theme_acquired)
|
if (!frame->theme_acquired)
|
||||||
frame->theme_data = window->screen->engine->acquire_frame (&info);
|
frame->theme_data = window->screen->engine->acquire_frame (&info);
|
||||||
|
|
||||||
@ -172,19 +190,6 @@ meta_frame_calc_geometry (MetaFrame *frame,
|
|||||||
|
|
||||||
window->screen->engine->fill_frame_geometry (&info, &geom,
|
window->screen->engine->fill_frame_geometry (&info, &geom,
|
||||||
frame->theme_data);
|
frame->theme_data);
|
||||||
|
|
||||||
frame->child_x = geom.left_width;
|
|
||||||
frame->child_y = geom.top_height;
|
|
||||||
frame->right_width = geom.right_width;
|
|
||||||
frame->bottom_height = geom.bottom_height;
|
|
||||||
|
|
||||||
frame->rect.width = frame->rect.width + geom.left_width + geom.right_width;
|
|
||||||
frame->rect.height = frame->rect.height + geom.top_height + geom.bottom_height;
|
|
||||||
|
|
||||||
meta_debug_spew ("Added top %d and bottom %d totalling %d over child height %d\n",
|
|
||||||
geom.top_height, geom.bottom_height, frame->rect.height, child_height);
|
|
||||||
|
|
||||||
frame->bg_pixel = geom.background_pixel;
|
|
||||||
|
|
||||||
*geomp = geom;
|
*geomp = geom;
|
||||||
}
|
}
|
||||||
@ -232,7 +237,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
{
|
{
|
||||||
MetaFrame *frame;
|
MetaFrame *frame;
|
||||||
XSetWindowAttributes attrs;
|
XSetWindowAttributes attrs;
|
||||||
MetaFrameGeometry geom;
|
|
||||||
|
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
return;
|
return;
|
||||||
@ -245,25 +249,14 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
frame->grab = NULL;
|
frame->grab = NULL;
|
||||||
frame->current_control = META_FRAME_CONTROL_NONE;
|
frame->current_control = META_FRAME_CONTROL_NONE;
|
||||||
frame->tooltip_timeout = 0;
|
frame->tooltip_timeout = 0;
|
||||||
|
|
||||||
/* This fills in frame->rect as well. */
|
|
||||||
meta_frame_calc_geometry (frame,
|
|
||||||
window->rect.width,
|
|
||||||
window->rect.height,
|
|
||||||
&geom);
|
|
||||||
|
|
||||||
meta_frame_calc_initial_pos (frame, window->rect.x, window->rect.y);
|
frame->rect = window->rect;
|
||||||
|
frame->child_x = 0;
|
||||||
meta_verbose ("Will create frame %d,%d %dx%d around window %s %d,%d %dx%d with child position inside frame %d,%d and gravity %d\n",
|
frame->child_y = 0;
|
||||||
frame->rect.x, frame->rect.y,
|
frame->bottom_height = 0;
|
||||||
frame->rect.width, frame->rect.height,
|
frame->right_width = 0;
|
||||||
window->desc,
|
frame->bg_pixel = 0;
|
||||||
window->rect.x, window->rect.y,
|
|
||||||
window->rect.width, window->rect.height,
|
|
||||||
frame->child_x, frame->child_y,
|
|
||||||
window->size_hints.win_gravity);
|
|
||||||
|
|
||||||
attrs.background_pixel = frame->bg_pixel;
|
|
||||||
attrs.event_mask = EVENT_MASK;
|
attrs.event_mask = EVENT_MASK;
|
||||||
|
|
||||||
frame->xwindow = XCreateWindow (window->display->xdisplay,
|
frame->xwindow = XCreateWindow (window->display->xdisplay,
|
||||||
@ -276,10 +269,10 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
window->depth,
|
window->depth,
|
||||||
InputOutput,
|
InputOutput,
|
||||||
window->xvisual,
|
window->xvisual,
|
||||||
CWBackPixel | CWEventMask,
|
CWEventMask,
|
||||||
&attrs);
|
&attrs);
|
||||||
|
|
||||||
meta_verbose ("Frame is 0x%lx\n", frame->xwindow);
|
meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow);
|
||||||
|
|
||||||
meta_display_register_x_window (window->display, &frame->xwindow, window);
|
meta_display_register_x_window (window->display, &frame->xwindow, window);
|
||||||
|
|
||||||
@ -299,21 +292,15 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
XReparentWindow (window->display->xdisplay,
|
XReparentWindow (window->display->xdisplay,
|
||||||
window->xwindow,
|
window->xwindow,
|
||||||
frame->xwindow,
|
frame->xwindow,
|
||||||
frame->child_x,
|
0, 0);
|
||||||
frame->child_y);
|
|
||||||
meta_error_trap_pop (window->display);
|
meta_error_trap_pop (window->display);
|
||||||
|
|
||||||
/* Update window's location */
|
|
||||||
window->rect.x = frame->child_x;
|
|
||||||
window->rect.y = frame->child_y;
|
|
||||||
|
|
||||||
/* stick frame to the window */
|
/* stick frame to the window */
|
||||||
window->frame = frame;
|
window->frame = frame;
|
||||||
|
|
||||||
/* Put our state back where it should be */
|
/* Ungrab server (FIXME after fixing Pango not to lock us up,
|
||||||
meta_window_queue_calc_showing (window);
|
* we need to recalc geometry before ungrabbing)
|
||||||
|
*/
|
||||||
/* Ungrab server */
|
|
||||||
meta_display_ungrab (window->display);
|
meta_display_ungrab (window->display);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,82 +354,24 @@ meta_window_destroy_frame (MetaWindow *window)
|
|||||||
meta_window_queue_calc_showing (window);
|
meta_window_queue_calc_showing (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Just a chunk of process_configure_event in window.c,
|
|
||||||
* moved here since it's the part that deals with
|
|
||||||
* the frame.
|
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
meta_frame_child_configure_request (MetaFrame *frame)
|
meta_frame_sync_to_window (MetaFrame *frame)
|
||||||
{
|
{
|
||||||
MetaFrameGeometry geom;
|
meta_verbose ("Syncing frame geometry %d,%d %dx%d pixel %ld\n",
|
||||||
|
frame->rect.x, frame->rect.y,
|
||||||
/* This fills in frame->rect as well. */
|
|
||||||
meta_frame_calc_geometry (frame,
|
|
||||||
frame->window->size_hints.width,
|
|
||||||
frame->window->size_hints.height,
|
|
||||||
&geom);
|
|
||||||
|
|
||||||
meta_frame_calc_initial_pos (frame,
|
|
||||||
frame->window->size_hints.x,
|
|
||||||
frame->window->size_hints.y);
|
|
||||||
|
|
||||||
set_background_none (frame);
|
|
||||||
XMoveResizeWindow (frame->window->display->xdisplay,
|
|
||||||
frame->xwindow,
|
|
||||||
frame->rect.x,
|
|
||||||
frame->rect.y,
|
|
||||||
frame->rect.width,
|
|
||||||
frame->rect.height);
|
|
||||||
set_background_color (frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_frame_recalc_now (MetaFrame *frame)
|
|
||||||
{
|
|
||||||
int old_child_x, old_child_y;
|
|
||||||
MetaFrameGeometry geom;
|
|
||||||
|
|
||||||
old_child_x = frame->child_x;
|
|
||||||
old_child_y = frame->child_y;
|
|
||||||
|
|
||||||
/* This fills in frame->rect as well. */
|
|
||||||
meta_frame_calc_geometry (frame,
|
|
||||||
frame->window->rect.width,
|
|
||||||
frame->window->rect.height,
|
|
||||||
&geom);
|
|
||||||
|
|
||||||
/* See if we need to move the frame to keep child in
|
|
||||||
* a constant position
|
|
||||||
*/
|
|
||||||
if (old_child_x != frame->child_x)
|
|
||||||
frame->rect.x += (frame->child_x - old_child_x);
|
|
||||||
if (old_child_y != frame->child_y)
|
|
||||||
frame->rect.y += (frame->child_y - old_child_y);
|
|
||||||
|
|
||||||
set_background_none (frame);
|
|
||||||
XMoveResizeWindow (frame->window->display->xdisplay,
|
|
||||||
frame->xwindow,
|
|
||||||
frame->rect.x,
|
|
||||||
frame->rect.y,
|
|
||||||
frame->rect.width,
|
|
||||||
frame->rect.height);
|
|
||||||
set_background_color (frame);
|
|
||||||
|
|
||||||
meta_verbose ("Frame of %s recalculated to %d,%d %d x %d child %d,%d\n",
|
|
||||||
frame->window->desc, frame->rect.x, frame->rect.y,
|
|
||||||
frame->rect.width, frame->rect.height,
|
frame->rect.width, frame->rect.height,
|
||||||
frame->child_x, frame->child_y);
|
frame->bg_pixel);
|
||||||
|
set_background_none (frame);
|
||||||
|
XMoveResizeWindow (frame->window->display->xdisplay,
|
||||||
|
frame->xwindow,
|
||||||
|
frame->rect.x,
|
||||||
|
frame->rect.y,
|
||||||
|
frame->rect.width,
|
||||||
|
frame->rect.height);
|
||||||
|
set_background_color (frame);
|
||||||
meta_frame_queue_draw (frame);
|
meta_frame_queue_draw (frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
meta_frame_queue_recalc (MetaFrame *frame)
|
|
||||||
{
|
|
||||||
/* FIXME, actually queue */
|
|
||||||
meta_frame_recalc_now (frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_frame_draw_now (MetaFrame *frame,
|
meta_frame_draw_now (MetaFrame *frame,
|
||||||
int x, int y, int width, int height)
|
int x, int y, int width, int height)
|
||||||
@ -776,7 +705,7 @@ get_menu_items (MetaFrame *frame,
|
|||||||
|
|
||||||
*ops |= (META_MESSAGE_MENU_DELETE | META_MESSAGE_MENU_WORKSPACES | META_MESSAGE_MENU_MINIMIZE);
|
*ops |= (META_MESSAGE_MENU_DELETE | META_MESSAGE_MENU_WORKSPACES | META_MESSAGE_MENU_MINIMIZE);
|
||||||
|
|
||||||
if (!(info->flags & META_FRAME_CONTROL_MINIMIZE))
|
if (!(info->flags & META_FRAME_CONTROL_ICONIFY))
|
||||||
*insensitive |= META_MESSAGE_MENU_MINIMIZE;
|
*insensitive |= META_MESSAGE_MENU_MINIMIZE;
|
||||||
|
|
||||||
if (!(info->flags & META_FRAME_CONTROL_DELETE))
|
if (!(info->flags & META_FRAME_CONTROL_DELETE))
|
||||||
|
19
src/frame.h
19
src/frame.h
@ -66,14 +66,25 @@ struct _MetaFrame
|
|||||||
|
|
||||||
void meta_window_ensure_frame (MetaWindow *window);
|
void meta_window_ensure_frame (MetaWindow *window);
|
||||||
void meta_window_destroy_frame (MetaWindow *window);
|
void meta_window_destroy_frame (MetaWindow *window);
|
||||||
void meta_frame_child_configure_request (MetaFrame *frame);
|
|
||||||
void meta_frame_recalc_now (MetaFrame *frame);
|
|
||||||
void meta_frame_queue_recalc (MetaFrame *frame);
|
|
||||||
void meta_frame_queue_draw (MetaFrame *frame);
|
void meta_frame_queue_draw (MetaFrame *frame);
|
||||||
gboolean meta_frame_event (MetaFrame *frame,
|
gboolean meta_frame_event (MetaFrame *frame,
|
||||||
XEvent *event);
|
XEvent *event);
|
||||||
|
|
||||||
|
/* These three should ONLY be called from meta_window_move_resize_internal */
|
||||||
|
void meta_frame_calc_geometry (MetaFrame *frame,
|
||||||
|
int child_width,
|
||||||
|
int child_height,
|
||||||
|
MetaFrameGeometry *geomp);
|
||||||
|
/* returns values suitable for meta_window_move */
|
||||||
|
void meta_frame_adjust_for_gravity (int win_gravity,
|
||||||
|
int frame_width,
|
||||||
|
int frame_height,
|
||||||
|
MetaFrameGeometry *fgeom,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int *win_root_x,
|
||||||
|
int *win_root_y);
|
||||||
|
void meta_frame_sync_to_window (MetaFrame *frame);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
27
src/session.c
Normal file
27
src/session.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* Metacity Session Management */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2001 Havoc Pennington
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "session.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
48
src/session.h
Normal file
48
src/session.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* Metacity Session Management */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2001 Havoc Pennington
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_SESSION_H
|
||||||
|
#define META_SESSION_H
|
||||||
|
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
|
typedef struct _MetaSessionInfo MetaSessionInfo;
|
||||||
|
|
||||||
|
struct _MetaSessionInfo
|
||||||
|
{
|
||||||
|
/* In -geometry format; x, y are affected by gravity, width, height
|
||||||
|
* are to be multiplied by resize increments, etc. This way we're
|
||||||
|
* robust against theme changes, client resize inc changes, client
|
||||||
|
* base size changes, and so on.
|
||||||
|
*/
|
||||||
|
MetaRectangle rect;
|
||||||
|
|
||||||
|
/* A per-screen index (_NET_WM_DESKTOP) */
|
||||||
|
int workspace;
|
||||||
|
};
|
||||||
|
|
||||||
|
MetaSessionInfo* meta_window_lookup_session_info (MetaWindow *window);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
660
src/window.c
660
src/window.c
@ -27,17 +27,28 @@
|
|||||||
|
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
static void constrain_size (MetaWindow *window,
|
static void constrain_size (MetaWindow *window,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int *new_width,
|
int *new_width,
|
||||||
int *new_height);
|
int *new_height);
|
||||||
|
static void constrain_position (MetaWindow *window,
|
||||||
|
MetaFrameGeometry *fgeom,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int *new_x,
|
||||||
|
int *new_y);
|
||||||
|
|
||||||
static int update_size_hints (MetaWindow *window);
|
static int update_size_hints (MetaWindow *window);
|
||||||
static int update_title (MetaWindow *window);
|
static int update_title (MetaWindow *window);
|
||||||
static int update_protocols (MetaWindow *window);
|
static int update_protocols (MetaWindow *window);
|
||||||
static int update_wm_hints (MetaWindow *window);
|
static int update_wm_hints (MetaWindow *window);
|
||||||
static int update_net_wm_state (MetaWindow *window);
|
static int update_net_wm_state (MetaWindow *window);
|
||||||
static int update_mwm_hints (MetaWindow *window);
|
static int update_mwm_hints (MetaWindow *window);
|
||||||
|
static int update_wm_class (MetaWindow *window);
|
||||||
|
static int update_transient_for (MetaWindow *window);
|
||||||
|
static void update_sm_hints (MetaWindow *window);
|
||||||
|
static int update_role (MetaWindow *window);
|
||||||
static int set_wm_state (MetaWindow *window,
|
static int set_wm_state (MetaWindow *window,
|
||||||
int state);
|
int state);
|
||||||
static void send_configure_notify (MetaWindow *window);
|
static void send_configure_notify (MetaWindow *window);
|
||||||
@ -52,6 +63,14 @@ static gboolean process_property_notify (MetaWindow *window,
|
|||||||
static void meta_window_show (MetaWindow *window);
|
static void meta_window_show (MetaWindow *window);
|
||||||
static void meta_window_hide (MetaWindow *window);
|
static void meta_window_hide (MetaWindow *window);
|
||||||
|
|
||||||
|
static void meta_window_move_resize_internal (MetaWindow *window,
|
||||||
|
gboolean move,
|
||||||
|
gboolean resize,
|
||||||
|
gboolean is_configure_request,
|
||||||
|
int root_x_nw,
|
||||||
|
int root_y_nw,
|
||||||
|
int w,
|
||||||
|
int h);
|
||||||
|
|
||||||
MetaWindow*
|
MetaWindow*
|
||||||
meta_window_new (MetaDisplay *display, Window xwindow)
|
meta_window_new (MetaDisplay *display, Window xwindow)
|
||||||
@ -155,6 +174,15 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
|||||||
window->has_close_func = TRUE;
|
window->has_close_func = TRUE;
|
||||||
window->has_minimize_func = TRUE;
|
window->has_minimize_func = TRUE;
|
||||||
window->has_maximize_func = TRUE;
|
window->has_maximize_func = TRUE;
|
||||||
|
|
||||||
|
window->res_class = NULL;
|
||||||
|
window->res_name = NULL;
|
||||||
|
window->role = NULL;
|
||||||
|
window->sm_client_id = NULL;
|
||||||
|
|
||||||
|
window->xtransient_for = None;
|
||||||
|
window->xgroup_leader = None;
|
||||||
|
window->xclient_leader = None;
|
||||||
|
|
||||||
meta_display_register_x_window (display, &window->xwindow, window);
|
meta_display_register_x_window (display, &window->xwindow, window);
|
||||||
|
|
||||||
@ -164,6 +192,10 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
|||||||
update_wm_hints (window);
|
update_wm_hints (window);
|
||||||
update_net_wm_state (window);
|
update_net_wm_state (window);
|
||||||
update_mwm_hints (window);
|
update_mwm_hints (window);
|
||||||
|
update_wm_class (window);
|
||||||
|
update_transient_for (window);
|
||||||
|
update_sm_hints (window); /* must come after transient_for */
|
||||||
|
update_role (window);
|
||||||
|
|
||||||
if (window->initially_iconic)
|
if (window->initially_iconic)
|
||||||
{
|
{
|
||||||
@ -171,10 +203,6 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
|||||||
window->minimized = TRUE;
|
window->minimized = TRUE;
|
||||||
meta_verbose ("Window %s asked to start out minimized\n", window->desc);
|
meta_verbose ("Window %s asked to start out minimized\n", window->desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_window_resize (window,
|
|
||||||
window->size_hints.width,
|
|
||||||
window->size_hints.height);
|
|
||||||
|
|
||||||
/* FIXME we have a tendency to set this then immediately
|
/* FIXME we have a tendency to set this then immediately
|
||||||
* change it again.
|
* change it again.
|
||||||
@ -186,7 +214,16 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
|||||||
|
|
||||||
meta_workspace_add_window (window->screen->active_workspace, window);
|
meta_workspace_add_window (window->screen->active_workspace, 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
|
||||||
|
* initial map is handled same as configure request
|
||||||
|
*/
|
||||||
|
meta_window_move_resize_internal (window, TRUE, TRUE, TRUE,
|
||||||
|
window->size_hints.x,
|
||||||
|
window->size_hints.y,
|
||||||
|
window->size_hints.width,
|
||||||
|
window->size_hints.height);
|
||||||
|
|
||||||
meta_window_queue_calc_showing (window);
|
meta_window_queue_calc_showing (window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
@ -371,34 +408,19 @@ meta_window_maximize (MetaWindow *window)
|
|||||||
{
|
{
|
||||||
if (!window->maximized)
|
if (!window->maximized)
|
||||||
{
|
{
|
||||||
int x, y;
|
|
||||||
|
|
||||||
window->maximized = TRUE;
|
window->maximized = TRUE;
|
||||||
|
|
||||||
/* save size/pos */
|
/* save size/pos as appropriate args for move_resize */
|
||||||
window->saved_rect = window->rect;
|
window->saved_rect = window->rect;
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
{
|
{
|
||||||
window->saved_rect.x += window->frame->rect.x;
|
window->saved_rect.x += window->frame->rect.x;
|
||||||
window->saved_rect.y += window->frame->rect.y;
|
window->saved_rect.y += window->frame->rect.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find top left corner */
|
|
||||||
x = window->screen->active_workspace->workarea.x;
|
|
||||||
y = window->screen->active_workspace->workarea.y;
|
|
||||||
if (window->frame)
|
|
||||||
{
|
|
||||||
x += window->frame->child_x;
|
|
||||||
y += window->frame->child_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* resize to current size with new maximization constraint,
|
/* move_resize with new maximization constraints
|
||||||
* and move to top-left corner
|
|
||||||
*/
|
*/
|
||||||
|
meta_window_queue_move_resize (window);
|
||||||
meta_window_move_resize (window, x, y,
|
|
||||||
window->rect.width, window->rect.height);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,8 +445,7 @@ meta_window_shade (MetaWindow *window)
|
|||||||
if (!window->shaded)
|
if (!window->shaded)
|
||||||
{
|
{
|
||||||
window->shaded = TRUE;
|
window->shaded = TRUE;
|
||||||
if (window->frame)
|
meta_window_queue_move_resize (window);
|
||||||
meta_frame_queue_recalc (window->frame);
|
|
||||||
meta_window_queue_calc_showing (window);
|
meta_window_queue_calc_showing (window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -435,9 +456,11 @@ meta_window_unshade (MetaWindow *window)
|
|||||||
if (window->shaded)
|
if (window->shaded)
|
||||||
{
|
{
|
||||||
window->shaded = FALSE;
|
window->shaded = FALSE;
|
||||||
if (window->frame)
|
meta_window_queue_move_resize (window);
|
||||||
meta_frame_queue_recalc (window->frame);
|
|
||||||
meta_window_queue_calc_showing (window);
|
meta_window_queue_calc_showing (window);
|
||||||
|
/* focus the window */
|
||||||
|
/* FIXME CurrentTime is bogus */
|
||||||
|
meta_window_focus (window, CurrentTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,17 +468,29 @@ static void
|
|||||||
meta_window_move_resize_internal (MetaWindow *window,
|
meta_window_move_resize_internal (MetaWindow *window,
|
||||||
gboolean move,
|
gboolean move,
|
||||||
gboolean resize,
|
gboolean resize,
|
||||||
|
gboolean is_configure_request,
|
||||||
int root_x_nw,
|
int root_x_nw,
|
||||||
int root_y_nw,
|
int root_y_nw,
|
||||||
int w,
|
int w,
|
||||||
int h)
|
int h)
|
||||||
{
|
{
|
||||||
|
XWindowChanges values;
|
||||||
|
unsigned int mask;
|
||||||
|
gboolean need_configure_notify;
|
||||||
|
MetaFrameGeometry fgeom;
|
||||||
|
|
||||||
if (resize)
|
if (resize)
|
||||||
meta_verbose ("Resizing %s to %d x %d\n", window->desc, w, h);
|
meta_verbose ("Resizing %s to %d x %d\n", window->desc, w, h);
|
||||||
if (move)
|
if (move)
|
||||||
meta_verbose ("Moving %s to %d,%d\n", window->desc,
|
meta_verbose ("Moving %s to %d,%d\n", window->desc,
|
||||||
root_x_nw, root_y_nw);
|
root_x_nw, root_y_nw);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* remember that root_x_nw, root_y_nw are bogus if not moving,
|
||||||
|
* and w, h are bogus if not resizing
|
||||||
|
*/
|
||||||
|
|
||||||
if (resize)
|
if (resize)
|
||||||
{
|
{
|
||||||
constrain_size (window, w, h, &w, &h);
|
constrain_size (window, w, h, &w, &h);
|
||||||
@ -468,24 +503,78 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
window->rect.height = h;
|
window->rect.height = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window->frame)
|
||||||
|
{
|
||||||
|
int new_w, new_h;
|
||||||
|
|
||||||
|
meta_frame_calc_geometry (window->frame,
|
||||||
|
window->rect.width,
|
||||||
|
window->rect.height,
|
||||||
|
&fgeom);
|
||||||
|
|
||||||
|
new_w = window->rect.width + fgeom.left_width + fgeom.right_width;
|
||||||
|
|
||||||
|
if (window->shaded)
|
||||||
|
new_h = fgeom.top_height;
|
||||||
|
else
|
||||||
|
new_h = window->rect.height + fgeom.top_height + fgeom.bottom_height;
|
||||||
|
|
||||||
|
/* FIXME could check to avoid XResizeWindow on frame */
|
||||||
|
|
||||||
|
window->frame->rect.width = new_w;
|
||||||
|
window->frame->rect.height = new_h;
|
||||||
|
|
||||||
|
meta_verbose ("Calculated frame size %dx%d\n",
|
||||||
|
window->frame->rect.width,
|
||||||
|
window->frame->rect.height);
|
||||||
|
}
|
||||||
|
|
||||||
if (move)
|
if (move)
|
||||||
{
|
{
|
||||||
|
if (is_configure_request && window->frame)
|
||||||
|
{
|
||||||
|
meta_frame_adjust_for_gravity (window->size_hints.win_gravity,
|
||||||
|
window->frame->rect.width,
|
||||||
|
window->frame->rect.height,
|
||||||
|
&fgeom,
|
||||||
|
root_x_nw,
|
||||||
|
root_y_nw,
|
||||||
|
&root_x_nw,
|
||||||
|
&root_y_nw);
|
||||||
|
|
||||||
|
meta_verbose ("Compensated position for gravity, new pos %d,%d\n",
|
||||||
|
root_x_nw, root_y_nw);
|
||||||
|
}
|
||||||
|
|
||||||
|
constrain_position (window,
|
||||||
|
window->frame ? &fgeom : NULL,
|
||||||
|
root_x_nw, root_y_nw,
|
||||||
|
&root_x_nw, &root_y_nw);
|
||||||
|
|
||||||
|
meta_verbose ("Constrained position to %d,%d\n",
|
||||||
|
root_x_nw, root_y_nw);
|
||||||
|
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
{
|
{
|
||||||
int new_x, new_y;
|
int new_x, new_y;
|
||||||
|
|
||||||
new_x = root_x_nw - window->frame->child_x;
|
new_x = root_x_nw - fgeom.left_width;
|
||||||
new_y = root_y_nw - window->frame->child_y;
|
new_y = root_y_nw - fgeom.top_height;
|
||||||
|
|
||||||
if (new_x == window->frame->rect.x &&
|
if (new_x == window->frame->rect.x &&
|
||||||
new_y == window->frame->rect.y)
|
new_y == window->frame->rect.y &&
|
||||||
|
window->rect.x == fgeom.left_width &&
|
||||||
|
window->rect.y == fgeom.top_height)
|
||||||
move = FALSE;
|
move = FALSE;
|
||||||
|
|
||||||
window->frame->rect.x = new_x;
|
window->frame->rect.x = new_x;
|
||||||
window->frame->rect.y = new_y;
|
window->frame->rect.y = new_y;
|
||||||
/* window->rect.x, window->rect.y remain relative to frame,
|
|
||||||
|
/* window->rect.x, window->rect.y are relative to frame,
|
||||||
* remember they are the server coords
|
* remember they are the server coords
|
||||||
*/
|
*/
|
||||||
|
window->rect.x = fgeom.left_width;
|
||||||
|
window->rect.y = fgeom.top_height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -498,47 +587,61 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fill in other frame member variables */
|
||||||
|
if (window->frame)
|
||||||
|
{
|
||||||
|
window->frame->child_x = fgeom.left_width;
|
||||||
|
window->frame->child_y = fgeom.top_height;
|
||||||
|
window->frame->right_width = fgeom.right_width;
|
||||||
|
window->frame->bottom_height = fgeom.bottom_height;
|
||||||
|
window->frame->bg_pixel = fgeom.background_pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this is a configure request and we change nothing, then we
|
||||||
|
* must send configure notify. In all cases we must send configure
|
||||||
|
* notify if we don't resize. ICCCM 4.1.5
|
||||||
|
*/
|
||||||
|
need_configure_notify =
|
||||||
|
(!resize) ||
|
||||||
|
(is_configure_request && !(move || resize || window->border_width != 0));
|
||||||
|
|
||||||
/* Sync our new size/pos with X as efficiently as possible */
|
/* Sync our new size/pos with X as efficiently as possible */
|
||||||
|
|
||||||
if (move && window->frame)
|
values.border_width = 0;
|
||||||
{
|
values.x = window->rect.x;
|
||||||
XMoveWindow (window->display->xdisplay,
|
values.y = window->rect.y;
|
||||||
window->frame->xwindow,
|
values.width = window->rect.width;
|
||||||
window->frame->rect.x,
|
values.height = window->rect.height;
|
||||||
window->frame->rect.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_error_trap_push (window->display);
|
|
||||||
if ((move && window->frame == NULL) && resize)
|
|
||||||
{
|
|
||||||
XMoveResizeWindow (window->display->xdisplay,
|
|
||||||
window->xwindow,
|
|
||||||
window->rect.x,
|
|
||||||
window->rect.y,
|
|
||||||
window->rect.width,
|
|
||||||
window->rect.height);
|
|
||||||
}
|
|
||||||
else if (move && window->frame == NULL)
|
|
||||||
{
|
|
||||||
XMoveWindow (window->display->xdisplay,
|
|
||||||
window->xwindow,
|
|
||||||
window->rect.x,
|
|
||||||
window->rect.y);
|
|
||||||
}
|
|
||||||
else if (resize)
|
|
||||||
{
|
|
||||||
XResizeWindow (window->display->xdisplay,
|
|
||||||
window->xwindow,
|
|
||||||
w, h);
|
|
||||||
|
|
||||||
}
|
|
||||||
meta_error_trap_pop (window->display);
|
|
||||||
|
|
||||||
|
mask = 0;
|
||||||
|
if (is_configure_request && window->border_width != 0)
|
||||||
|
mask |= CWBorderWidth; /* must force to 0 */
|
||||||
if (move)
|
if (move)
|
||||||
send_configure_notify (window);
|
mask |= (CWX | CWY);
|
||||||
|
if (resize)
|
||||||
|
mask |= (CWWidth | CWHeight);
|
||||||
|
|
||||||
if (window->frame && resize)
|
if (mask != 0)
|
||||||
meta_frame_queue_recalc (window->frame);
|
{
|
||||||
|
meta_verbose ("Syncing new geometry to client, border: %s pos: %s size: %s\n",
|
||||||
|
mask & CWBorderWidth ? "true" : "false",
|
||||||
|
mask & CWX ? "true" : "false",
|
||||||
|
mask & CWWidth ? "true" : "false");
|
||||||
|
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
XConfigureWindow (window->display->xdisplay,
|
||||||
|
window->xwindow,
|
||||||
|
mask,
|
||||||
|
&values);
|
||||||
|
meta_error_trap_pop (window->display);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now do the frame */
|
||||||
|
if (window->frame)
|
||||||
|
meta_frame_sync_to_window (window->frame);
|
||||||
|
|
||||||
|
if (need_configure_notify)
|
||||||
|
send_configure_notify (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -546,7 +649,7 @@ meta_window_resize (MetaWindow *window,
|
|||||||
int w,
|
int w,
|
||||||
int h)
|
int h)
|
||||||
{
|
{
|
||||||
meta_window_move_resize_internal (window, FALSE, TRUE, -1, -1, w, h);
|
meta_window_move_resize_internal (window, FALSE, TRUE, FALSE, -1, -1, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -554,7 +657,7 @@ meta_window_move (MetaWindow *window,
|
|||||||
int root_x_nw,
|
int root_x_nw,
|
||||||
int root_y_nw)
|
int root_y_nw)
|
||||||
{
|
{
|
||||||
meta_window_move_resize_internal (window, TRUE, FALSE,
|
meta_window_move_resize_internal (window, TRUE, FALSE, FALSE,
|
||||||
root_x_nw, root_y_nw, -1, -1);
|
root_x_nw, root_y_nw, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,11 +668,40 @@ meta_window_move_resize (MetaWindow *window,
|
|||||||
int w,
|
int w,
|
||||||
int h)
|
int h)
|
||||||
{
|
{
|
||||||
meta_window_move_resize_internal (window, TRUE, TRUE,
|
meta_window_move_resize_internal (window, TRUE, TRUE, FALSE,
|
||||||
root_x_nw, root_y_nw,
|
root_x_nw, root_y_nw,
|
||||||
w, h);
|
w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_queue_move_resize (MetaWindow *window)
|
||||||
|
{
|
||||||
|
/* FIXME actually queue */
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
meta_window_get_position (window, &x, &y);
|
||||||
|
|
||||||
|
meta_window_move_resize (window, x, y,
|
||||||
|
window->rect.width, window->rect.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_get_position (MetaWindow *window,
|
||||||
|
int *x,
|
||||||
|
int *y)
|
||||||
|
{
|
||||||
|
if (window->frame)
|
||||||
|
{
|
||||||
|
*x = window->frame->rect.x + window->frame->child_x;
|
||||||
|
*y = window->frame->rect.y + window->frame->child_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*x = window->rect.x;
|
||||||
|
*y = window->rect.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_window_delete (MetaWindow *window,
|
meta_window_delete (MetaWindow *window,
|
||||||
Time timestamp)
|
Time timestamp)
|
||||||
@ -832,7 +964,17 @@ meta_window_client_message (MetaWindow *window,
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
else if (event->xclient.message_type ==
|
||||||
|
display->atom_wm_change_state)
|
||||||
|
{
|
||||||
|
meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n",
|
||||||
|
event->xclient.data.l[0]);
|
||||||
|
if (event->xclient.data.l[0] == IconicState)
|
||||||
|
meta_window_minimize (window);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -844,30 +986,27 @@ process_property_notify (MetaWindow *window,
|
|||||||
event->atom == window->display->atom_net_wm_name)
|
event->atom == window->display->atom_net_wm_name)
|
||||||
{
|
{
|
||||||
update_title (window);
|
update_title (window);
|
||||||
|
|
||||||
if (window->frame)
|
meta_window_queue_move_resize (window);
|
||||||
meta_frame_queue_recalc (window->frame);
|
|
||||||
}
|
}
|
||||||
else if (event->atom == XA_WM_NORMAL_HINTS)
|
else if (event->atom == XA_WM_NORMAL_HINTS)
|
||||||
{
|
{
|
||||||
update_size_hints (window);
|
update_size_hints (window);
|
||||||
|
|
||||||
/* See if we need to constrain current size */
|
/* See if we need to constrain current size */
|
||||||
meta_window_resize (window, window->rect.width, window->rect.height);
|
meta_window_queue_move_resize (window);
|
||||||
}
|
}
|
||||||
else if (event->atom == window->display->atom_wm_protocols)
|
else if (event->atom == window->display->atom_wm_protocols)
|
||||||
{
|
{
|
||||||
update_protocols (window);
|
update_protocols (window);
|
||||||
|
|
||||||
if (window->frame)
|
meta_window_queue_move_resize (window);
|
||||||
meta_frame_queue_recalc (window->frame);
|
|
||||||
}
|
}
|
||||||
else if (event->atom == XA_WM_HINTS)
|
else if (event->atom == XA_WM_HINTS)
|
||||||
{
|
{
|
||||||
update_wm_hints (window);
|
update_wm_hints (window);
|
||||||
|
|
||||||
if (window->frame)
|
meta_window_queue_move_resize (window);
|
||||||
meta_frame_queue_recalc (window->frame);
|
|
||||||
}
|
}
|
||||||
else if (event->atom == window->display->atom_motif_wm_hints)
|
else if (event->atom == window->display->atom_motif_wm_hints)
|
||||||
{
|
{
|
||||||
@ -878,8 +1017,29 @@ process_property_notify (MetaWindow *window,
|
|||||||
else
|
else
|
||||||
meta_window_destroy_frame (window);
|
meta_window_destroy_frame (window);
|
||||||
|
|
||||||
if (window->frame)
|
meta_window_queue_move_resize (window);
|
||||||
meta_frame_queue_recalc (window->frame);
|
}
|
||||||
|
else if (event->atom == XA_WM_CLASS)
|
||||||
|
{
|
||||||
|
update_wm_class (window);
|
||||||
|
}
|
||||||
|
else if (event->atom == XA_WM_TRANSIENT_FOR)
|
||||||
|
{
|
||||||
|
update_transient_for (window);
|
||||||
|
|
||||||
|
meta_window_queue_move_resize (window);
|
||||||
|
}
|
||||||
|
else if (event->atom ==
|
||||||
|
window->display->atom_wm_window_role)
|
||||||
|
{
|
||||||
|
update_role (window);
|
||||||
|
}
|
||||||
|
else if (event->atom ==
|
||||||
|
window->display->atom_wm_client_leader ||
|
||||||
|
event->atom ==
|
||||||
|
window->display->atom_sm_client_id)
|
||||||
|
{
|
||||||
|
meta_warning ("Broken client changed client leader window or SM client ID\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -891,6 +1051,9 @@ send_configure_notify (MetaWindow *window)
|
|||||||
XEvent event;
|
XEvent event;
|
||||||
|
|
||||||
/* 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;
|
||||||
@ -929,9 +1092,6 @@ process_configure_request (MetaWindow *window,
|
|||||||
int border_width)
|
int border_width)
|
||||||
{
|
{
|
||||||
/* ICCCM 4.1.5 */
|
/* ICCCM 4.1.5 */
|
||||||
XWindowChanges values;
|
|
||||||
unsigned int mask;
|
|
||||||
int client_x, client_y;
|
|
||||||
|
|
||||||
/* Note that x, y is the corner of the window border,
|
/* Note that x, y is the corner of the window border,
|
||||||
* and width, height is the size of the window inside
|
* and width, height is the size of the window inside
|
||||||
@ -948,74 +1108,13 @@ process_configure_request (MetaWindow *window,
|
|||||||
window->size_hints.y = y;
|
window->size_hints.y = y;
|
||||||
window->size_hints.width = width;
|
window->size_hints.width = width;
|
||||||
window->size_hints.height = height;
|
window->size_hints.height = height;
|
||||||
|
|
||||||
constrain_size (window,
|
|
||||||
window->size_hints.width,
|
|
||||||
window->size_hints.height,
|
|
||||||
&window->size_hints.width,
|
|
||||||
&window->size_hints.height);
|
|
||||||
|
|
||||||
meta_verbose ("Constrained configure request size to %d x %d\n",
|
meta_window_move_resize_internal (window, TRUE, TRUE, TRUE,
|
||||||
window->size_hints.width, window->size_hints.height);
|
window->size_hints.x,
|
||||||
|
window->size_hints.y,
|
||||||
|
window->size_hints.width,
|
||||||
|
window->size_hints.height);
|
||||||
|
|
||||||
if (window->frame)
|
|
||||||
{
|
|
||||||
meta_frame_child_configure_request (window->frame);
|
|
||||||
client_x = window->frame->child_x;
|
|
||||||
client_y = window->frame->child_y;
|
|
||||||
meta_verbose ("Will place client window %s inside frame at %d,%d\n",
|
|
||||||
window->desc, client_x, client_y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
client_x = window->size_hints.x;
|
|
||||||
client_y = window->size_hints.y;
|
|
||||||
meta_verbose ("Will place client window %s at root coordinate %d,%d\n",
|
|
||||||
window->desc, client_x, client_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
values.border_width = 0;
|
|
||||||
values.x = client_x;
|
|
||||||
values.y = client_y;
|
|
||||||
values.width = window->size_hints.width;
|
|
||||||
values.height = window->size_hints.height;
|
|
||||||
|
|
||||||
mask = 0;
|
|
||||||
if (window->border_width != 0)
|
|
||||||
mask |= CWBorderWidth;
|
|
||||||
if (values.x != window->rect.x)
|
|
||||||
mask |= CWX;
|
|
||||||
if (values.y != window->rect.y)
|
|
||||||
mask |= CWY;
|
|
||||||
if (values.width != window->rect.width)
|
|
||||||
mask |= CWWidth;
|
|
||||||
if (values.height != window->rect.height)
|
|
||||||
mask |= CWHeight;
|
|
||||||
|
|
||||||
window->rect.x = values.x;
|
|
||||||
window->rect.y = values.y;
|
|
||||||
window->rect.width = values.width;
|
|
||||||
window->rect.height = values.height;
|
|
||||||
|
|
||||||
meta_error_trap_push (window->display);
|
|
||||||
XConfigureWindow (window->display->xdisplay,
|
|
||||||
window->xwindow,
|
|
||||||
mask,
|
|
||||||
&values);
|
|
||||||
meta_error_trap_pop (window->display);
|
|
||||||
|
|
||||||
if (mask & (CWBorderWidth | CWWidth | CWHeight))
|
|
||||||
{
|
|
||||||
/* Resizing, no synthetic ConfigureNotify, third case in 4.1.5 */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Moving but not resizing, second case in 4.1.5, or
|
|
||||||
* have to send the ConfigureNotify, first case in 4.1.5
|
|
||||||
*/
|
|
||||||
send_configure_notify (window);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1296,12 +1395,15 @@ update_wm_hints (MetaWindow *window)
|
|||||||
{
|
{
|
||||||
window->input = (hints->flags & InputHint) != 0;
|
window->input = (hints->flags & InputHint) != 0;
|
||||||
|
|
||||||
window->initially_iconic = (hints->initial_state == IconicState);
|
if (hints->flags & StateHint)
|
||||||
|
window->initially_iconic = (hints->initial_state == IconicState);
|
||||||
/* FIXME there are a few others there. */
|
|
||||||
|
|
||||||
meta_verbose ("Read WM_HINTS input: %d iconic: %d\n",
|
if (hints->flags & WindowGroupHint)
|
||||||
window->input, window->initially_iconic);
|
window->xgroup_leader = hints->window_group;
|
||||||
|
|
||||||
|
meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%ld\n",
|
||||||
|
window->input, window->initially_iconic,
|
||||||
|
window->xgroup_leader);
|
||||||
|
|
||||||
XFree (hints);
|
XFree (hints);
|
||||||
}
|
}
|
||||||
@ -1452,6 +1554,202 @@ update_mwm_hints (MetaWindow *window)
|
|||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
update_wm_class (MetaWindow *window)
|
||||||
|
{
|
||||||
|
XClassHint ch;
|
||||||
|
|
||||||
|
if (window->res_class)
|
||||||
|
g_free (window->res_class);
|
||||||
|
if (window->res_name)
|
||||||
|
g_free (window->res_name);
|
||||||
|
|
||||||
|
window->res_class = NULL;
|
||||||
|
window->res_name = NULL;
|
||||||
|
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
|
||||||
|
ch.res_name = NULL;
|
||||||
|
ch.res_class = NULL;
|
||||||
|
|
||||||
|
XGetClassHint (window->display->xdisplay,
|
||||||
|
window->xwindow,
|
||||||
|
&ch);
|
||||||
|
|
||||||
|
if (ch.res_name)
|
||||||
|
{
|
||||||
|
window->res_name = g_strdup (ch.res_name);
|
||||||
|
XFree (ch.res_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch.res_class)
|
||||||
|
{
|
||||||
|
window->res_class = g_strdup (ch.res_class);
|
||||||
|
XFree (ch.res_class);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_verbose ("Window %s class: '%s' name: '%s'\n",
|
||||||
|
window->desc,
|
||||||
|
window->res_class ? window->res_class : "(null)",
|
||||||
|
window->res_name ? window->res_name : "(null)");
|
||||||
|
|
||||||
|
return meta_error_trap_pop (window->display);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_string_prop (MetaDisplay *display,
|
||||||
|
Window xwindow,
|
||||||
|
Atom atom,
|
||||||
|
char **strp)
|
||||||
|
{
|
||||||
|
Atom type;
|
||||||
|
gint format;
|
||||||
|
gulong nitems;
|
||||||
|
gulong bytes_after;
|
||||||
|
guchar *str;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
str = NULL;
|
||||||
|
XGetWindowProperty (display->xdisplay,
|
||||||
|
xwindow, atom,
|
||||||
|
0, G_MAXLONG,
|
||||||
|
False, XA_STRING, &type, &format, &nitems,
|
||||||
|
&bytes_after, (guchar **)&str);
|
||||||
|
|
||||||
|
result = meta_error_trap_pop (display);
|
||||||
|
if (result != Success)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (type != XA_STRING)
|
||||||
|
return -1; /* whatever */
|
||||||
|
|
||||||
|
*strp = g_strdup (str);
|
||||||
|
|
||||||
|
XFree (str);
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Window
|
||||||
|
read_client_leader (MetaDisplay *display,
|
||||||
|
Window xwindow)
|
||||||
|
{
|
||||||
|
Atom type;
|
||||||
|
gint format;
|
||||||
|
gulong nitems;
|
||||||
|
gulong bytes_after;
|
||||||
|
Window *leader;
|
||||||
|
int result;
|
||||||
|
Window retval;
|
||||||
|
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
leader = NULL;
|
||||||
|
XGetWindowProperty (display->xdisplay, xwindow,
|
||||||
|
display->atom_wm_client_leader,
|
||||||
|
0, G_MAXLONG,
|
||||||
|
False, XA_WINDOW, &type, &format, &nitems,
|
||||||
|
&bytes_after, (guchar **)&leader);
|
||||||
|
|
||||||
|
result = meta_error_trap_pop (display);
|
||||||
|
if (result != Success)
|
||||||
|
return None;
|
||||||
|
|
||||||
|
if (type != XA_WINDOW)
|
||||||
|
return None;
|
||||||
|
|
||||||
|
retval = *leader;
|
||||||
|
|
||||||
|
XFree (leader);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_sm_hints (MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaWindow *w;
|
||||||
|
Window leader;
|
||||||
|
|
||||||
|
window->xclient_leader = None;
|
||||||
|
window->sm_client_id = NULL;
|
||||||
|
|
||||||
|
/* If not on the current window, we can get the client
|
||||||
|
* leader from transient parents. If we find a client
|
||||||
|
* leader, we read the SM_CLIENT_ID from it.
|
||||||
|
*/
|
||||||
|
leader = None;
|
||||||
|
w = window;
|
||||||
|
while (w != NULL)
|
||||||
|
{
|
||||||
|
leader = read_client_leader (window->display, w->xwindow);
|
||||||
|
|
||||||
|
if (leader != None)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (w->xtransient_for == None)
|
||||||
|
break;
|
||||||
|
|
||||||
|
w = meta_display_lookup_x_window (w->display, w->xtransient_for);
|
||||||
|
|
||||||
|
if (w == window)
|
||||||
|
break; /* Cute, someone thought they'd make a transient_for cycle */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leader)
|
||||||
|
{
|
||||||
|
window->xclient_leader = leader;
|
||||||
|
read_string_prop (window->display, leader,
|
||||||
|
window->display->atom_sm_client_id,
|
||||||
|
&window->sm_client_id);
|
||||||
|
|
||||||
|
meta_verbose ("Window %s client leader: 0x%ld SM_CLIENT_ID: '%s'\n",
|
||||||
|
window->desc, window->xclient_leader, window->sm_client_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
meta_verbose ("Didn't find a client leader for %s\n", window->desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
update_role (MetaWindow *window)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (window->role)
|
||||||
|
g_free (window->role);
|
||||||
|
window->role = NULL;
|
||||||
|
|
||||||
|
result = read_string_prop (window->display, window->xwindow,
|
||||||
|
window->display->atom_wm_window_role,
|
||||||
|
&window->role);
|
||||||
|
|
||||||
|
meta_verbose ("Updated role of %s to '%s'\n",
|
||||||
|
window->desc, window->role ? window->role : "(null)");
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
update_transient_for (MetaWindow *window)
|
||||||
|
{
|
||||||
|
Window w;
|
||||||
|
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
w = None;
|
||||||
|
XGetTransientForHint (window->display->xdisplay,
|
||||||
|
window->xwindow,
|
||||||
|
&w);
|
||||||
|
window->xtransient_for = w;
|
||||||
|
|
||||||
|
if (window->xtransient_for != None)
|
||||||
|
meta_verbose ("Window %s transient for 0x%ld\n", window->desc,
|
||||||
|
window->xtransient_for);
|
||||||
|
else
|
||||||
|
meta_verbose ("Window %s is not transient\n", window->desc);
|
||||||
|
|
||||||
|
return meta_error_trap_pop (window->display);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
constrain_size (MetaWindow *window,
|
constrain_size (MetaWindow *window,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
@ -1469,6 +1767,8 @@ constrain_size (MetaWindow *window,
|
|||||||
int delta;
|
int delta;
|
||||||
double min_aspect, max_aspect;
|
double min_aspect, max_aspect;
|
||||||
int minw, minh, maxw, maxh, fullw, fullh;
|
int minw, minh, maxw, maxh, fullw, fullh;
|
||||||
|
|
||||||
|
/* frame member variables should NEVER be used in here */
|
||||||
|
|
||||||
#define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
|
#define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
|
||||||
|
|
||||||
@ -1560,3 +1860,43 @@ constrain_size (MetaWindow *window,
|
|||||||
*new_height = height;
|
*new_height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constrain_position (MetaWindow *window,
|
||||||
|
MetaFrameGeometry *fgeom,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int *new_x,
|
||||||
|
int *new_y)
|
||||||
|
{
|
||||||
|
int nw_x, nw_y;
|
||||||
|
|
||||||
|
/* frame member variables should NEVER be used in here, only
|
||||||
|
* MetaFrameGeometry
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* find furthest northwest corner */
|
||||||
|
nw_x = window->screen->active_workspace->workarea.x;
|
||||||
|
nw_y = window->screen->active_workspace->workarea.y;
|
||||||
|
if (window->frame)
|
||||||
|
{
|
||||||
|
nw_x += fgeom->left_width;
|
||||||
|
nw_y += fgeom->top_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* don't allow moving titlebar off the top or left */
|
||||||
|
if (x < nw_x)
|
||||||
|
x = nw_x;
|
||||||
|
if (y < nw_y)
|
||||||
|
y = nw_y;
|
||||||
|
|
||||||
|
if (window->maximized)
|
||||||
|
{
|
||||||
|
if (x != nw_x)
|
||||||
|
x = nw_x;
|
||||||
|
if (y != nw_y)
|
||||||
|
y = nw_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
*new_x = x;
|
||||||
|
*new_y = y;
|
||||||
|
}
|
||||||
|
21
src/window.h
21
src/window.h
@ -39,6 +39,18 @@ struct _MetaWindow
|
|||||||
char *desc; /* used in debug spew */
|
char *desc; /* used in debug spew */
|
||||||
char *title;
|
char *title;
|
||||||
|
|
||||||
|
/* NOTE these four are not in UTF-8, we just treat them as random
|
||||||
|
* binary data
|
||||||
|
*/
|
||||||
|
char *res_class;
|
||||||
|
char *res_name;
|
||||||
|
char *role;
|
||||||
|
char *sm_client_id;
|
||||||
|
|
||||||
|
Window xtransient_for;
|
||||||
|
Window xgroup_leader;
|
||||||
|
Window xclient_leader;
|
||||||
|
|
||||||
/* Whether we're maximized */
|
/* Whether we're maximized */
|
||||||
guint maximized : 1;
|
guint maximized : 1;
|
||||||
|
|
||||||
@ -127,6 +139,15 @@ void meta_window_move_resize (MetaWindow *window,
|
|||||||
int root_y_nw,
|
int root_y_nw,
|
||||||
int w,
|
int w,
|
||||||
int h);
|
int h);
|
||||||
|
/* This recalcs the window/frame size, and recalcs the frame
|
||||||
|
* size/contents as well.
|
||||||
|
*/
|
||||||
|
void meta_window_queue_move_resize (MetaWindow *window);
|
||||||
|
|
||||||
|
/* this gets root coords */
|
||||||
|
void meta_window_get_position (MetaWindow *window,
|
||||||
|
int *x,
|
||||||
|
int *y);
|
||||||
void meta_window_delete (MetaWindow *window,
|
void meta_window_delete (MetaWindow *window,
|
||||||
Time timestamp);
|
Time timestamp);
|
||||||
void meta_window_focus (MetaWindow *window,
|
void meta_window_focus (MetaWindow *window,
|
||||||
|
Loading…
Reference in New Issue
Block a user