...
This commit is contained in:
parent
c533bc838e
commit
146361b6f5
@ -55,6 +55,8 @@ metacity_SOURCES= \
|
||||
main.h \
|
||||
screen.c \
|
||||
screen.h \
|
||||
session.c \
|
||||
session.h \
|
||||
theme.c \
|
||||
theme.h \
|
||||
uislave.c \
|
||||
|
@ -86,7 +86,11 @@ meta_display_open (const char *name)
|
||||
"_NET_WM_STATE_MAXIMIZED_HORZ",
|
||||
"_NET_WM_STATE_MAXIMIZED_VERT",
|
||||
"_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)];
|
||||
|
||||
@ -136,6 +140,10 @@ meta_display_open (const char *name)
|
||||
display->atom_net_wm_state_maximized_vert = atoms[10];
|
||||
display->atom_net_wm_desktop = atoms[11];
|
||||
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;
|
||||
i = 0;
|
||||
@ -175,6 +183,13 @@ meta_display_open (const char *name)
|
||||
display->last_button_xwindow = None;
|
||||
display->last_button_num = 0;
|
||||
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 */
|
||||
tmp = display->screens;
|
||||
@ -241,6 +256,8 @@ meta_display_close (MetaDisplay *display)
|
||||
* unregister windows
|
||||
*/
|
||||
g_hash_table_destroy (display->window_ids);
|
||||
|
||||
XDestroyWindow (display->xdisplay, display->leader_window);
|
||||
|
||||
meta_event_queue_free (display->events);
|
||||
XCloseDisplay (display->xdisplay);
|
||||
|
@ -43,6 +43,8 @@ struct _MetaDisplay
|
||||
char *name;
|
||||
Display *xdisplay;
|
||||
|
||||
Window leader_window;
|
||||
|
||||
Atom atom_net_wm_name;
|
||||
Atom atom_wm_protocols;
|
||||
Atom atom_wm_take_focus;
|
||||
@ -56,6 +58,10 @@ struct _MetaDisplay
|
||||
Atom atom_net_wm_state_maximized_vert;
|
||||
Atom atom_net_wm_desktop;
|
||||
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,
|
||||
* 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;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_frame_calc_initial_pos (MetaFrame *frame,
|
||||
int child_root_x, int child_root_y)
|
||||
|
||||
/* 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 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 (window->size_hints.win_gravity)
|
||||
switch (win_gravity)
|
||||
{
|
||||
case NorthWestGravity:
|
||||
frame->rect.x = child_root_x;
|
||||
frame->rect.y = child_root_y;
|
||||
x = child_root_x;
|
||||
y = child_root_y;
|
||||
break;
|
||||
case NorthGravity:
|
||||
frame->rect.x = child_root_x - frame->rect.width / 2;
|
||||
frame->rect.y = child_root_y;
|
||||
x = child_root_x - frame_width / 2;
|
||||
y = child_root_y;
|
||||
break;
|
||||
case NorthEastGravity:
|
||||
frame->rect.x = child_root_x - frame->rect.width;
|
||||
frame->rect.y = child_root_y;
|
||||
x = child_root_x - frame_width;
|
||||
y = child_root_y;
|
||||
break;
|
||||
case WestGravity:
|
||||
frame->rect.x = child_root_x;
|
||||
frame->rect.y = child_root_y - frame->rect.height / 2;
|
||||
x = child_root_x;
|
||||
y = child_root_y - frame_height / 2;
|
||||
break;
|
||||
case CenterGravity:
|
||||
frame->rect.x = child_root_x - frame->rect.width / 2;
|
||||
frame->rect.y = child_root_y - frame->rect.height / 2;
|
||||
x = child_root_x - frame_width / 2;
|
||||
y = child_root_y - frame_height / 2;
|
||||
break;
|
||||
case EastGravity:
|
||||
frame->rect.x = child_root_x - frame->rect.width;
|
||||
frame->rect.y = child_root_y - frame->rect.height / 2;
|
||||
x = child_root_x - frame_width;
|
||||
y = child_root_y - frame_height / 2;
|
||||
break;
|
||||
case SouthWestGravity:
|
||||
frame->rect.x = child_root_x;
|
||||
frame->rect.y = child_root_y - frame->rect.height;
|
||||
x = child_root_x;
|
||||
y = child_root_y - frame_height;
|
||||
break;
|
||||
case SouthGravity:
|
||||
frame->rect.x = child_root_x - frame->rect.width / 2;
|
||||
frame->rect.y = child_root_y - frame->rect.height;
|
||||
x = child_root_x - frame_width / 2;
|
||||
y = child_root_y - frame_height;
|
||||
break;
|
||||
case SouthEastGravity:
|
||||
frame->rect.x = child_root_x - frame->rect.width;
|
||||
frame->rect.y = child_root_y - frame->rect.height;
|
||||
x = child_root_x - frame_width;
|
||||
y = child_root_y - frame_height;
|
||||
break;
|
||||
case StaticGravity:
|
||||
default:
|
||||
frame->rect.x = child_root_x - frame->child_x;
|
||||
frame->rect.y = child_root_y - frame->child_y;
|
||||
x = child_root_x - fgeom->left_width;
|
||||
y = child_root_y - fgeom->top_height;
|
||||
break;
|
||||
}
|
||||
|
||||
*win_root_x = x + fgeom->left_width;
|
||||
*win_root_y = y + fgeom->top_height;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
meta_frame_calc_geometry (MetaFrame *frame,
|
||||
int child_width, int child_height,
|
||||
MetaFrameGeometry *geomp)
|
||||
@ -143,20 +159,22 @@ meta_frame_calc_geometry (MetaFrame *frame,
|
||||
MetaWindow *window;
|
||||
|
||||
/* Remember this is called from the constructor
|
||||
* pre-window-creation.
|
||||
* pre-X-window-creation.
|
||||
*/
|
||||
|
||||
window = frame->window;
|
||||
|
||||
frame->rect.width = child_width;
|
||||
|
||||
if (window->shaded)
|
||||
frame->rect.height = 0;
|
||||
else
|
||||
frame->rect.height = child_height;
|
||||
/* frame->rect isn't useful yet */
|
||||
|
||||
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)
|
||||
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,
|
||||
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;
|
||||
}
|
||||
@ -232,7 +237,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
{
|
||||
MetaFrame *frame;
|
||||
XSetWindowAttributes attrs;
|
||||
MetaFrameGeometry geom;
|
||||
|
||||
if (window->frame)
|
||||
return;
|
||||
@ -245,25 +249,14 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
frame->grab = NULL;
|
||||
frame->current_control = META_FRAME_CONTROL_NONE;
|
||||
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);
|
||||
|
||||
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->rect.x, frame->rect.y,
|
||||
frame->rect.width, frame->rect.height,
|
||||
window->desc,
|
||||
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;
|
||||
frame->rect = window->rect;
|
||||
frame->child_x = 0;
|
||||
frame->child_y = 0;
|
||||
frame->bottom_height = 0;
|
||||
frame->right_width = 0;
|
||||
frame->bg_pixel = 0;
|
||||
|
||||
attrs.event_mask = EVENT_MASK;
|
||||
|
||||
frame->xwindow = XCreateWindow (window->display->xdisplay,
|
||||
@ -276,10 +269,10 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
window->depth,
|
||||
InputOutput,
|
||||
window->xvisual,
|
||||
CWBackPixel | CWEventMask,
|
||||
CWEventMask,
|
||||
&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);
|
||||
|
||||
@ -299,21 +292,15 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
XReparentWindow (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
frame->xwindow,
|
||||
frame->child_x,
|
||||
frame->child_y);
|
||||
0, 0);
|
||||
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 */
|
||||
window->frame = frame;
|
||||
|
||||
/* Put our state back where it should be */
|
||||
meta_window_queue_calc_showing (window);
|
||||
|
||||
/* Ungrab server */
|
||||
/* Ungrab server (FIXME after fixing Pango not to lock us up,
|
||||
* we need to recalc geometry before ungrabbing)
|
||||
*/
|
||||
meta_display_ungrab (window->display);
|
||||
}
|
||||
|
||||
@ -367,82 +354,24 @@ meta_window_destroy_frame (MetaWindow *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
|
||||
meta_frame_child_configure_request (MetaFrame *frame)
|
||||
meta_frame_sync_to_window (MetaFrame *frame)
|
||||
{
|
||||
MetaFrameGeometry geom;
|
||||
|
||||
/* 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,
|
||||
meta_verbose ("Syncing frame geometry %d,%d %dx%d pixel %ld\n",
|
||||
frame->rect.x, frame->rect.y,
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_queue_recalc (MetaFrame *frame)
|
||||
{
|
||||
/* FIXME, actually queue */
|
||||
meta_frame_recalc_now (frame);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_frame_draw_now (MetaFrame *frame,
|
||||
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);
|
||||
|
||||
if (!(info->flags & META_FRAME_CONTROL_MINIMIZE))
|
||||
if (!(info->flags & META_FRAME_CONTROL_ICONIFY))
|
||||
*insensitive |= META_MESSAGE_MENU_MINIMIZE;
|
||||
|
||||
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_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);
|
||||
gboolean meta_frame_event (MetaFrame *frame,
|
||||
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
|
||||
|
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>
|
||||
|
||||
static void constrain_size (MetaWindow *window,
|
||||
int width,
|
||||
int height,
|
||||
int *new_width,
|
||||
int *new_height);
|
||||
static void constrain_size (MetaWindow *window,
|
||||
int width,
|
||||
int height,
|
||||
int *new_width,
|
||||
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_title (MetaWindow *window);
|
||||
static int update_protocols (MetaWindow *window);
|
||||
static int update_wm_hints (MetaWindow *window);
|
||||
static int update_net_wm_state (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,
|
||||
int state);
|
||||
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_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*
|
||||
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_minimize_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);
|
||||
|
||||
@ -164,6 +192,10 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
||||
update_wm_hints (window);
|
||||
update_net_wm_state (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)
|
||||
{
|
||||
@ -171,10 +203,6 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
||||
window->minimized = TRUE;
|
||||
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
|
||||
* change it again.
|
||||
@ -186,7 +214,16 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
||||
|
||||
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);
|
||||
|
||||
return window;
|
||||
@ -371,34 +408,19 @@ meta_window_maximize (MetaWindow *window)
|
||||
{
|
||||
if (!window->maximized)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
window->maximized = TRUE;
|
||||
|
||||
/* save size/pos */
|
||||
/* save size/pos as appropriate args for move_resize */
|
||||
window->saved_rect = window->rect;
|
||||
if (window->frame)
|
||||
{
|
||||
window->saved_rect.x += window->frame->rect.x;
|
||||
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,
|
||||
* and move to top-left corner
|
||||
/* move_resize with new maximization constraints
|
||||
*/
|
||||
|
||||
meta_window_move_resize (window, x, y,
|
||||
window->rect.width, window->rect.height);
|
||||
meta_window_queue_move_resize (window);
|
||||
}
|
||||
}
|
||||
|
||||
@ -423,8 +445,7 @@ meta_window_shade (MetaWindow *window)
|
||||
if (!window->shaded)
|
||||
{
|
||||
window->shaded = TRUE;
|
||||
if (window->frame)
|
||||
meta_frame_queue_recalc (window->frame);
|
||||
meta_window_queue_move_resize (window);
|
||||
meta_window_queue_calc_showing (window);
|
||||
}
|
||||
}
|
||||
@ -435,9 +456,11 @@ meta_window_unshade (MetaWindow *window)
|
||||
if (window->shaded)
|
||||
{
|
||||
window->shaded = FALSE;
|
||||
if (window->frame)
|
||||
meta_frame_queue_recalc (window->frame);
|
||||
meta_window_queue_move_resize (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,
|
||||
gboolean move,
|
||||
gboolean resize,
|
||||
gboolean is_configure_request,
|
||||
int root_x_nw,
|
||||
int root_y_nw,
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
{
|
||||
XWindowChanges values;
|
||||
unsigned int mask;
|
||||
gboolean need_configure_notify;
|
||||
MetaFrameGeometry fgeom;
|
||||
|
||||
if (resize)
|
||||
meta_verbose ("Resizing %s to %d x %d\n", window->desc, w, h);
|
||||
if (move)
|
||||
meta_verbose ("Moving %s to %d,%d\n", window->desc,
|
||||
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)
|
||||
{
|
||||
constrain_size (window, w, h, &w, &h);
|
||||
@ -468,24 +503,78 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
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 (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)
|
||||
{
|
||||
int new_x, new_y;
|
||||
|
||||
new_x = root_x_nw - window->frame->child_x;
|
||||
new_y = root_y_nw - window->frame->child_y;
|
||||
new_x = root_x_nw - fgeom.left_width;
|
||||
new_y = root_y_nw - fgeom.top_height;
|
||||
|
||||
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;
|
||||
|
||||
window->frame->rect.x = new_x;
|
||||
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
|
||||
*/
|
||||
window->rect.x = fgeom.left_width;
|
||||
window->rect.y = fgeom.top_height;
|
||||
}
|
||||
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 */
|
||||
|
||||
if (move && window->frame)
|
||||
{
|
||||
XMoveWindow (window->display->xdisplay,
|
||||
window->frame->xwindow,
|
||||
window->frame->rect.x,
|
||||
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);
|
||||
values.border_width = 0;
|
||||
values.x = window->rect.x;
|
||||
values.y = window->rect.y;
|
||||
values.width = window->rect.width;
|
||||
values.height = window->rect.height;
|
||||
|
||||
mask = 0;
|
||||
if (is_configure_request && window->border_width != 0)
|
||||
mask |= CWBorderWidth; /* must force to 0 */
|
||||
if (move)
|
||||
send_configure_notify (window);
|
||||
mask |= (CWX | CWY);
|
||||
if (resize)
|
||||
mask |= (CWWidth | CWHeight);
|
||||
|
||||
if (window->frame && resize)
|
||||
meta_frame_queue_recalc (window->frame);
|
||||
if (mask != 0)
|
||||
{
|
||||
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
|
||||
@ -546,7 +649,7 @@ meta_window_resize (MetaWindow *window,
|
||||
int w,
|
||||
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
|
||||
@ -554,7 +657,7 @@ meta_window_move (MetaWindow *window,
|
||||
int root_x_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);
|
||||
}
|
||||
|
||||
@ -565,11 +668,40 @@ meta_window_move_resize (MetaWindow *window,
|
||||
int w,
|
||||
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,
|
||||
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
|
||||
meta_window_delete (MetaWindow *window,
|
||||
Time timestamp)
|
||||
@ -832,7 +964,17 @@ meta_window_client_message (MetaWindow *window,
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -844,30 +986,27 @@ process_property_notify (MetaWindow *window,
|
||||
event->atom == window->display->atom_net_wm_name)
|
||||
{
|
||||
update_title (window);
|
||||
|
||||
if (window->frame)
|
||||
meta_frame_queue_recalc (window->frame);
|
||||
|
||||
meta_window_queue_move_resize (window);
|
||||
}
|
||||
else if (event->atom == XA_WM_NORMAL_HINTS)
|
||||
{
|
||||
update_size_hints (window);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
update_protocols (window);
|
||||
|
||||
if (window->frame)
|
||||
meta_frame_queue_recalc (window->frame);
|
||||
meta_window_queue_move_resize (window);
|
||||
}
|
||||
else if (event->atom == XA_WM_HINTS)
|
||||
{
|
||||
update_wm_hints (window);
|
||||
|
||||
if (window->frame)
|
||||
meta_frame_queue_recalc (window->frame);
|
||||
meta_window_queue_move_resize (window);
|
||||
}
|
||||
else if (event->atom == window->display->atom_motif_wm_hints)
|
||||
{
|
||||
@ -878,8 +1017,29 @@ process_property_notify (MetaWindow *window,
|
||||
else
|
||||
meta_window_destroy_frame (window);
|
||||
|
||||
if (window->frame)
|
||||
meta_frame_queue_recalc (window->frame);
|
||||
meta_window_queue_move_resize (window);
|
||||
}
|
||||
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;
|
||||
@ -891,6 +1051,9 @@ send_configure_notify (MetaWindow *window)
|
||||
XEvent event;
|
||||
|
||||
/* from twm */
|
||||
|
||||
meta_verbose ("Sending synthetic ConfigureNotify to %s\n",
|
||||
window->desc);
|
||||
|
||||
event.type = ConfigureNotify;
|
||||
event.xconfigure.display = window->display->xdisplay;
|
||||
@ -929,9 +1092,6 @@ process_configure_request (MetaWindow *window,
|
||||
int border_width)
|
||||
{
|
||||
/* 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,
|
||||
* 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.width = width;
|
||||
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",
|
||||
window->size_hints.width, window->size_hints.height);
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1296,12 +1395,15 @@ update_wm_hints (MetaWindow *window)
|
||||
{
|
||||
window->input = (hints->flags & InputHint) != 0;
|
||||
|
||||
window->initially_iconic = (hints->initial_state == IconicState);
|
||||
|
||||
/* FIXME there are a few others there. */
|
||||
if (hints->flags & StateHint)
|
||||
window->initially_iconic = (hints->initial_state == IconicState);
|
||||
|
||||
meta_verbose ("Read WM_HINTS input: %d iconic: %d\n",
|
||||
window->input, window->initially_iconic);
|
||||
if (hints->flags & WindowGroupHint)
|
||||
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);
|
||||
}
|
||||
@ -1452,6 +1554,202 @@ update_mwm_hints (MetaWindow *window)
|
||||
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
|
||||
constrain_size (MetaWindow *window,
|
||||
int width, int height,
|
||||
@ -1469,6 +1767,8 @@ constrain_size (MetaWindow *window,
|
||||
int delta;
|
||||
double min_aspect, max_aspect;
|
||||
int minw, minh, maxw, maxh, fullw, fullh;
|
||||
|
||||
/* frame member variables should NEVER be used in here */
|
||||
|
||||
#define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
|
||||
|
||||
@ -1560,3 +1860,43 @@ constrain_size (MetaWindow *window,
|
||||
*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 *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 */
|
||||
guint maximized : 1;
|
||||
|
||||
@ -127,6 +139,15 @@ void meta_window_move_resize (MetaWindow *window,
|
||||
int root_y_nw,
|
||||
int w,
|
||||
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,
|
||||
Time timestamp);
|
||||
void meta_window_focus (MetaWindow *window,
|
||||
|
Loading…
Reference in New Issue
Block a user