mirror of
https://github.com/brl/mutter.git
synced 2025-02-16 13:24:09 +00:00
...
This commit is contained in:
parent
c506b48624
commit
1cd2915ba3
@ -25,6 +25,7 @@
|
|||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
|
#include "errors.h"
|
||||||
|
|
||||||
static GSList *all_displays = NULL;
|
static GSList *all_displays = NULL;
|
||||||
static void meta_spew_event (MetaDisplay *display,
|
static void meta_spew_event (MetaDisplay *display,
|
||||||
@ -180,26 +181,24 @@ meta_display_close (MetaDisplay *display)
|
|||||||
g_hash_table_foreach (display->window_ids,
|
g_hash_table_foreach (display->window_ids,
|
||||||
listify_func,
|
listify_func,
|
||||||
&winlist);
|
&winlist);
|
||||||
|
|
||||||
g_hash_table_destroy (display->window_ids);
|
|
||||||
|
|
||||||
winlist = g_slist_sort (winlist, ptrcmp);
|
winlist = g_slist_sort (winlist, ptrcmp);
|
||||||
|
|
||||||
tmp = winlist;
|
tmp = winlist;
|
||||||
while (tmp != NULL)
|
while (tmp != NULL)
|
||||||
{
|
{
|
||||||
/* If the next node doesn't contain this window
|
|
||||||
* a second time, delete the window.
|
|
||||||
*/
|
|
||||||
g_assert (tmp->data != NULL);
|
|
||||||
|
|
||||||
if (tmp->next == NULL ||
|
if (tmp->next == NULL ||
|
||||||
(tmp->next && tmp->next->data != tmp->data))
|
(tmp->next && tmp->next->data != tmp->data))
|
||||||
meta_window_free (tmp->data);
|
meta_window_free (tmp->data);
|
||||||
|
|
||||||
tmp = tmp->data;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
g_slist_free (winlist);
|
g_slist_free (winlist);
|
||||||
|
|
||||||
|
/* Must be after all calls to meta_window_free() since they
|
||||||
|
* unregister windows
|
||||||
|
*/
|
||||||
|
g_hash_table_destroy (display->window_ids);
|
||||||
|
|
||||||
meta_event_queue_free (display->events);
|
meta_event_queue_free (display->events);
|
||||||
XCloseDisplay (display->xdisplay);
|
XCloseDisplay (display->xdisplay);
|
||||||
@ -352,12 +351,34 @@ event_queue_callback (MetaEventQueue *queue,
|
|||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
break;
|
break;
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
|
/* We handle it here if an undecorated window
|
||||||
|
* is involved, otherwise we handle it in frame.c
|
||||||
|
*/
|
||||||
|
/* do this even if window->has_focus to avoid races */
|
||||||
|
if (window)
|
||||||
|
meta_window_focus (window, event->xcrossing.time);
|
||||||
break;
|
break;
|
||||||
case LeaveNotify:
|
case LeaveNotify:
|
||||||
break;
|
break;
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
if (window != window->display->focus_window)
|
||||||
|
window->display->focus_window = window;
|
||||||
|
window->has_focus = TRUE;
|
||||||
|
if (window->frame)
|
||||||
|
meta_frame_queue_draw (window->frame);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FocusOut:
|
case FocusOut:
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
if (window == window->display->focus_window)
|
||||||
|
window->display->focus_window = NULL;
|
||||||
|
window->has_focus = FALSE;
|
||||||
|
if (window->frame)
|
||||||
|
meta_frame_queue_draw (window->frame);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case KeymapNotify:
|
case KeymapNotify:
|
||||||
break;
|
break;
|
||||||
@ -470,8 +491,6 @@ event_get_modified_window (MetaDisplay *display,
|
|||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
case ButtonRelease:
|
case ButtonRelease:
|
||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
case EnterNotify:
|
|
||||||
case LeaveNotify:
|
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
case FocusOut:
|
case FocusOut:
|
||||||
case KeymapNotify:
|
case KeymapNotify:
|
||||||
@ -486,8 +505,10 @@ event_get_modified_window (MetaDisplay *display,
|
|||||||
case SelectionNotify:
|
case SelectionNotify:
|
||||||
case ColormapNotify:
|
case ColormapNotify:
|
||||||
case ClientMessage:
|
case ClientMessage:
|
||||||
|
case EnterNotify:
|
||||||
|
case LeaveNotify:
|
||||||
return event->xany.window;
|
return event->xany.window;
|
||||||
|
|
||||||
case CreateNotify:
|
case CreateNotify:
|
||||||
return event->xcreatewindow.window;
|
return event->xcreatewindow.window;
|
||||||
|
|
||||||
@ -558,9 +579,21 @@ meta_spew_event (MetaDisplay *display,
|
|||||||
break;
|
break;
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
name = "EnterNotify";
|
name = "EnterNotify";
|
||||||
|
extra = g_strdup_printf ("win: 0x%lx root: 0x%lx subwindow: 0x%lx mode: %d detail: %d\n",
|
||||||
|
event->xcrossing.window,
|
||||||
|
event->xcrossing.root,
|
||||||
|
event->xcrossing.subwindow,
|
||||||
|
event->xcrossing.mode,
|
||||||
|
event->xcrossing.detail);
|
||||||
break;
|
break;
|
||||||
case LeaveNotify:
|
case LeaveNotify:
|
||||||
name = "LeaveNotify";
|
name = "LeaveNotify";
|
||||||
|
extra = g_strdup_printf ("win: 0x%lx root: 0x%lx subwindow: 0x%lx mode: %d detail: %d\n",
|
||||||
|
event->xcrossing.window,
|
||||||
|
event->xcrossing.root,
|
||||||
|
event->xcrossing.subwindow,
|
||||||
|
event->xcrossing.mode,
|
||||||
|
event->xcrossing.detail);
|
||||||
break;
|
break;
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
name = "FocusIn";
|
name = "FocusIn";
|
||||||
|
@ -42,6 +42,11 @@ struct _MetaDisplay
|
|||||||
Atom atom_wm_protocols;
|
Atom atom_wm_protocols;
|
||||||
Atom atom_wm_take_focus;
|
Atom atom_wm_take_focus;
|
||||||
Atom atom_wm_delete_window;
|
Atom atom_wm_delete_window;
|
||||||
|
|
||||||
|
/* This is the actual window from focus events,
|
||||||
|
* not the one we last set
|
||||||
|
*/
|
||||||
|
MetaWindow *focus_window;
|
||||||
|
|
||||||
/*< private-ish >*/
|
/*< private-ish >*/
|
||||||
MetaEventQueue *events;
|
MetaEventQueue *events;
|
||||||
@ -61,7 +66,6 @@ void meta_display_grab (MetaDisplay *display);
|
|||||||
void meta_display_ungrab (MetaDisplay *display);
|
void meta_display_ungrab (MetaDisplay *display);
|
||||||
PangoContext* meta_display_get_pango_context (MetaDisplay *display);
|
PangoContext* meta_display_get_pango_context (MetaDisplay *display);
|
||||||
|
|
||||||
|
|
||||||
/* A given MetaWindow may have various X windows that "belong"
|
/* A given MetaWindow may have various X windows that "belong"
|
||||||
* to it, such as the frame window.
|
* to it, such as the frame window.
|
||||||
*/
|
*/
|
||||||
|
72
src/frame.c
72
src/frame.c
@ -32,6 +32,9 @@ meta_frame_init_info (MetaFrame *frame,
|
|||||||
META_FRAME_ALLOWS_DELETE | META_FRAME_ALLOWS_MENU |
|
META_FRAME_ALLOWS_DELETE | META_FRAME_ALLOWS_MENU |
|
||||||
META_FRAME_ALLOWS_ICONIFY | META_FRAME_ALLOWS_MAXIMIZE |
|
META_FRAME_ALLOWS_ICONIFY | META_FRAME_ALLOWS_MAXIMIZE |
|
||||||
META_FRAME_ALLOWS_RESIZE;
|
META_FRAME_ALLOWS_RESIZE;
|
||||||
|
|
||||||
|
if (frame->window->has_focus)
|
||||||
|
info->flags |= META_FRAME_HAS_FOCUS;
|
||||||
|
|
||||||
info->drawable = None;
|
info->drawable = None;
|
||||||
info->xoffset = 0;
|
info->xoffset = 0;
|
||||||
@ -142,6 +145,9 @@ meta_frame_calc_geometry (MetaFrame *frame,
|
|||||||
frame->rect.width = frame->rect.width + geom.left_width + geom.right_width;
|
frame->rect.width = frame->rect.width + geom.left_width + geom.right_width;
|
||||||
frame->rect.height = frame->rect.height + geom.top_height + geom.bottom_height;
|
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;
|
frame->bg_pixel = geom.background_pixel;
|
||||||
|
|
||||||
*geomp = geom;
|
*geomp = geom;
|
||||||
@ -157,6 +163,18 @@ set_background_none (MetaFrame *frame)
|
|||||||
frame->xwindow,
|
frame->xwindow,
|
||||||
CWBackPixmap,
|
CWBackPixmap,
|
||||||
&attrs);
|
&attrs);
|
||||||
|
|
||||||
|
meta_debug_spew ("Frame size %d,%d %dx%d window size %d,%d %dx%d window pos %d,%d\n",
|
||||||
|
frame->rect.x,
|
||||||
|
frame->rect.y,
|
||||||
|
frame->rect.width,
|
||||||
|
frame->rect.height,
|
||||||
|
frame->window->rect.x,
|
||||||
|
frame->window->rect.y,
|
||||||
|
frame->window->rect.width,
|
||||||
|
frame->window->rect.height,
|
||||||
|
frame->child_x,
|
||||||
|
frame->child_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -211,8 +229,9 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
attrs.background_pixel = frame->bg_pixel;
|
attrs.background_pixel = frame->bg_pixel;
|
||||||
attrs.event_mask =
|
attrs.event_mask =
|
||||||
StructureNotifyMask | SubstructureNotifyMask | ExposureMask |
|
StructureNotifyMask | SubstructureNotifyMask | ExposureMask |
|
||||||
ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask |
|
ButtonPressMask | ButtonReleaseMask |
|
||||||
PointerMotionMask | PointerMotionHintMask;
|
PointerMotionMask | PointerMotionHintMask |
|
||||||
|
EnterWindowMask | LeaveWindowMask;
|
||||||
|
|
||||||
frame->xwindow = XCreateWindow (window->display->xdisplay,
|
frame->xwindow = XCreateWindow (window->display->xdisplay,
|
||||||
window->screen->xroot,
|
window->screen->xroot,
|
||||||
@ -230,9 +249,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
meta_verbose ("Frame is 0x%lx\n", frame->xwindow);
|
meta_verbose ("Frame is 0x%lx\n", frame->xwindow);
|
||||||
|
|
||||||
frame->action = META_FRAME_ACTION_NONE;
|
frame->action = META_FRAME_ACTION_NONE;
|
||||||
frame->last_x = 0;
|
|
||||||
frame->last_y = 0;
|
|
||||||
frame->start_button = 0;
|
|
||||||
|
|
||||||
meta_display_register_x_window (window->display, &frame->xwindow, window);
|
meta_display_register_x_window (window->display, &frame->xwindow, window);
|
||||||
|
|
||||||
@ -502,31 +518,32 @@ static void
|
|||||||
update_move (MetaFrame *frame)
|
update_move (MetaFrame *frame)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
int new_x, new_y;
|
int dx, dy;
|
||||||
|
|
||||||
frame_query_root_pointer (frame, &x, &y);
|
frame_query_root_pointer (frame, &x, &y);
|
||||||
|
|
||||||
new_x = frame->rect.x + (x - frame->last_x);
|
dx = x - frame->start_root_x;
|
||||||
new_y = frame->rect.y + (y - frame->last_y);
|
dy = y - frame->start_root_y;
|
||||||
frame->last_x = x;
|
|
||||||
frame->last_y = y;
|
|
||||||
|
|
||||||
meta_frame_move (frame, new_x, new_y);
|
meta_frame_move (frame,
|
||||||
|
frame->start_window_x + dx,
|
||||||
|
frame->start_window_y + dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_resize_se (MetaFrame *frame)
|
update_resize_se (MetaFrame *frame)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
int new_w, new_h;
|
int dx, dy;
|
||||||
|
|
||||||
frame_query_root_pointer (frame, &x, &y);
|
frame_query_root_pointer (frame, &x, &y);
|
||||||
|
|
||||||
new_w = frame->window->rect.width + (x - frame->last_x);
|
dx = x - frame->start_root_x;
|
||||||
new_h = frame->window->rect.height + (y - frame->last_y);
|
dy = y - frame->start_root_y;
|
||||||
frame->last_x = x;
|
|
||||||
frame->last_y = y;
|
|
||||||
|
|
||||||
meta_window_resize (frame->window, new_w, new_h);
|
meta_window_resize (frame->window,
|
||||||
|
frame->start_window_x + dx,
|
||||||
|
frame->start_window_y + dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -555,8 +572,10 @@ meta_frame_event (MetaFrame *frame,
|
|||||||
meta_verbose ("Begin move on %s\n",
|
meta_verbose ("Begin move on %s\n",
|
||||||
frame->window->desc);
|
frame->window->desc);
|
||||||
frame->action = META_FRAME_ACTION_MOVING;
|
frame->action = META_FRAME_ACTION_MOVING;
|
||||||
frame->last_x = event->xbutton.x_root;
|
frame->start_root_x = event->xbutton.x_root;
|
||||||
frame->last_y = event->xbutton.y_root;
|
frame->start_root_y = event->xbutton.y_root;
|
||||||
|
frame->start_window_x = frame->rect.x;
|
||||||
|
frame->start_window_y = frame->rect.y;
|
||||||
frame->start_button = event->xbutton.button;
|
frame->start_button = event->xbutton.button;
|
||||||
}
|
}
|
||||||
else if (control == META_FRAME_CONTROL_DELETE &&
|
else if (control == META_FRAME_CONTROL_DELETE &&
|
||||||
@ -565,6 +584,7 @@ meta_frame_event (MetaFrame *frame,
|
|||||||
/* FIXME delete event */
|
/* FIXME delete event */
|
||||||
meta_verbose ("Close control clicked on %s\n",
|
meta_verbose ("Close control clicked on %s\n",
|
||||||
frame->window->desc);
|
frame->window->desc);
|
||||||
|
meta_window_delete (frame->window, event->xbutton.time);
|
||||||
}
|
}
|
||||||
else if (control == META_FRAME_CONTROL_RESIZE_SE &&
|
else if (control == META_FRAME_CONTROL_RESIZE_SE &&
|
||||||
event->xbutton.button == 1)
|
event->xbutton.button == 1)
|
||||||
@ -572,8 +592,10 @@ meta_frame_event (MetaFrame *frame,
|
|||||||
meta_verbose ("Resize control clicked on %s\n",
|
meta_verbose ("Resize control clicked on %s\n",
|
||||||
frame->window->desc);
|
frame->window->desc);
|
||||||
frame->action = META_FRAME_ACTION_RESIZING_SE;
|
frame->action = META_FRAME_ACTION_RESIZING_SE;
|
||||||
frame->last_x = event->xbutton.x_root;
|
frame->start_root_x = event->xbutton.x_root;
|
||||||
frame->last_y = event->xbutton.y_root;
|
frame->start_root_y = event->xbutton.y_root;
|
||||||
|
frame->start_window_x = frame->window->rect.width;
|
||||||
|
frame->start_window_y = frame->window->rect.height;
|
||||||
frame->start_button = event->xbutton.button;
|
frame->start_button = event->xbutton.button;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -622,6 +644,12 @@ meta_frame_event (MetaFrame *frame,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
|
/* We handle it here if a decorated window
|
||||||
|
* is involved, otherwise we handle it in display.c
|
||||||
|
*/
|
||||||
|
/* do this even if window->has_focus to avoid races */
|
||||||
|
meta_window_focus (frame->window,
|
||||||
|
event->xcrossing.time);
|
||||||
break;
|
break;
|
||||||
case LeaveNotify:
|
case LeaveNotify:
|
||||||
break;
|
break;
|
||||||
|
@ -50,8 +50,11 @@ struct _MetaFrame
|
|||||||
gulong bg_pixel;
|
gulong bg_pixel;
|
||||||
|
|
||||||
MetaFrameAction action;
|
MetaFrameAction action;
|
||||||
/* reference point for drags */
|
/* initial mouse position for drags */
|
||||||
int last_x, last_y;
|
int start_root_x, start_root_y;
|
||||||
|
/* initial window size or initial window position for drags */
|
||||||
|
int start_window_x, start_window_y;
|
||||||
|
/* button doing the dragging */
|
||||||
int start_button;
|
int start_button;
|
||||||
|
|
||||||
guint theme_acquired : 1;
|
guint theme_acquired : 1;
|
||||||
|
@ -10,5 +10,6 @@ elif test -z "$DEBUG"; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
Xnest :1 -scrns $SCREENS -geometry 270x270 &
|
Xnest :1 -scrns $SCREENS -geometry 270x270 &
|
||||||
|
DISPLAY=:1 xsetroot -solid royalblue3
|
||||||
METACITY_UISLAVE_DIR=./uislave DISPLAY=:1 unst libtool --mode=execute $DEBUG ./metacity
|
METACITY_UISLAVE_DIR=./uislave DISPLAY=:1 unst libtool --mode=execute $DEBUG ./metacity
|
||||||
killall Xnest
|
killall Xnest
|
||||||
|
126
src/theme.c
126
src/theme.c
@ -55,6 +55,9 @@ struct _DefaultScreenData
|
|||||||
GC fg_gc;
|
GC fg_gc;
|
||||||
GC light_gc;
|
GC light_gc;
|
||||||
GC dark_gc;
|
GC dark_gc;
|
||||||
|
GC black_gc;
|
||||||
|
GC selected_gc;
|
||||||
|
GC selected_text_gc;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FIXME store this on the screen */
|
/* FIXME store this on the screen */
|
||||||
@ -69,13 +72,13 @@ default_acquire_frame (MetaFrameInfo *info)
|
|||||||
|
|
||||||
if (screen_data == NULL)
|
if (screen_data == NULL)
|
||||||
{
|
{
|
||||||
|
PangoColor color;
|
||||||
|
|
||||||
screen_data = g_new (DefaultScreenData, 1);
|
screen_data = g_new (DefaultScreenData, 1);
|
||||||
|
|
||||||
vals.foreground = meta_get_x_pixel (info->screen,
|
vals.foreground = meta_get_x_pixel (info->screen,
|
||||||
&info->colors->fg[META_STATE_NORMAL]);
|
&info->colors->fg[META_STATE_NORMAL]);
|
||||||
/* FIXME memory-inefficient, could use the same one for all frames
|
|
||||||
* w/ the same root window
|
|
||||||
*/
|
|
||||||
screen_data->text_gc = XCreateGC (info->display,
|
screen_data->text_gc = XCreateGC (info->display,
|
||||||
RootWindowOfScreen (info->screen),
|
RootWindowOfScreen (info->screen),
|
||||||
GCForeground,
|
GCForeground,
|
||||||
@ -98,6 +101,27 @@ default_acquire_frame (MetaFrameInfo *info)
|
|||||||
RootWindowOfScreen (info->screen),
|
RootWindowOfScreen (info->screen),
|
||||||
GCForeground,
|
GCForeground,
|
||||||
&vals);
|
&vals);
|
||||||
|
|
||||||
|
vals.foreground = meta_get_x_pixel (info->screen,
|
||||||
|
&info->colors->bg[META_STATE_SELECTED]);
|
||||||
|
screen_data->selected_gc = XCreateGC (info->display,
|
||||||
|
RootWindowOfScreen (info->screen),
|
||||||
|
GCForeground,
|
||||||
|
&vals);
|
||||||
|
vals.foreground = meta_get_x_pixel (info->screen,
|
||||||
|
&info->colors->fg[META_STATE_SELECTED]);
|
||||||
|
screen_data->selected_text_gc = XCreateGC (info->display,
|
||||||
|
RootWindowOfScreen (info->screen),
|
||||||
|
GCForeground,
|
||||||
|
&vals);
|
||||||
|
|
||||||
|
color.red = color.green = color.blue = 0;
|
||||||
|
vals.foreground = meta_get_x_pixel (info->screen,
|
||||||
|
&color);
|
||||||
|
screen_data->black_gc = XCreateGC (info->display,
|
||||||
|
RootWindowOfScreen (info->screen),
|
||||||
|
GCForeground,
|
||||||
|
&vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
d = g_new (DefaultFrameData, 1);
|
d = g_new (DefaultFrameData, 1);
|
||||||
@ -126,13 +150,15 @@ default_release_frame (MetaFrameInfo *info,
|
|||||||
g_free (d);
|
g_free (d);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VERTICAL_TITLE_PAD 2
|
#define ABOVE_TITLE_PAD 4
|
||||||
#define HORIZONTAL_TITLE_PAD 3
|
#define BELOW_TITLE_PAD 3
|
||||||
|
#define RIGHT_TITLE_PAD 4
|
||||||
|
#define LEFT_TITLE_PAD 3
|
||||||
#define VERTICAL_TEXT_PAD 2
|
#define VERTICAL_TEXT_PAD 2
|
||||||
#define HORIZONTAL_TEXT_PAD 2
|
#define HORIZONTAL_TEXT_PAD 2
|
||||||
#define LEFT_WIDTH 2
|
#define LEFT_WIDTH 6
|
||||||
#define RIGHT_WIDTH 2
|
#define RIGHT_WIDTH 6
|
||||||
#define BOTTOM_HEIGHT 5
|
#define BOTTOM_HEIGHT 7
|
||||||
#define SPACER_SPACING 3
|
#define SPACER_SPACING 3
|
||||||
#define SPACER_WIDTH 2
|
#define SPACER_WIDTH 2
|
||||||
#define SPACER_HEIGHT 10
|
#define SPACER_HEIGHT 10
|
||||||
@ -149,7 +175,7 @@ calc_geometry (MetaFrameInfo *info,
|
|||||||
int button_y;
|
int button_y;
|
||||||
int title_right_edge;
|
int title_right_edge;
|
||||||
|
|
||||||
fgeom->top_height = MAX (d->layout_height + VERTICAL_TITLE_PAD * 2 + VERTICAL_TEXT_PAD * 2,
|
fgeom->top_height = MAX (d->layout_height + VERTICAL_TEXT_PAD * 2 + ABOVE_TITLE_PAD + BELOW_TITLE_PAD,
|
||||||
BUTTON_HEIGHT + BUTTON_PAD * 2);
|
BUTTON_HEIGHT + BUTTON_PAD * 2);
|
||||||
|
|
||||||
fgeom->left_width = LEFT_WIDTH;
|
fgeom->left_width = LEFT_WIDTH;
|
||||||
@ -229,7 +255,7 @@ calc_geometry (MetaFrameInfo *info,
|
|||||||
fgeom->spacer_rect.height = 0;
|
fgeom->spacer_rect.height = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
title_right_edge = x - HORIZONTAL_TITLE_PAD;
|
title_right_edge = x - RIGHT_TITLE_PAD;
|
||||||
|
|
||||||
/* Now x changes to be position from the left */
|
/* Now x changes to be position from the left */
|
||||||
x = fgeom->left_width;
|
x = fgeom->left_width;
|
||||||
@ -251,10 +277,10 @@ calc_geometry (MetaFrameInfo *info,
|
|||||||
fgeom->menu_rect.height = 0;
|
fgeom->menu_rect.height = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fgeom->title_rect.x = x + BUTTON_PAD;
|
fgeom->title_rect.x = x + LEFT_TITLE_PAD;
|
||||||
fgeom->title_rect.y = VERTICAL_TITLE_PAD;
|
fgeom->title_rect.y = ABOVE_TITLE_PAD;
|
||||||
fgeom->title_rect.width = title_right_edge - fgeom->title_rect.x;
|
fgeom->title_rect.width = title_right_edge - fgeom->title_rect.x;
|
||||||
fgeom->title_rect.height = fgeom->top_height - VERTICAL_TITLE_PAD * 2;
|
fgeom->title_rect.height = fgeom->top_height - ABOVE_TITLE_PAD - BELOW_TITLE_PAD;
|
||||||
|
|
||||||
if (fgeom->title_rect.width < 0)
|
if (fgeom->title_rect.width < 0)
|
||||||
fgeom->title_rect.width = 0;
|
fgeom->title_rect.width = 0;
|
||||||
@ -299,10 +325,11 @@ draw_vline (MetaFrameInfo *info,
|
|||||||
int y2,
|
int y2,
|
||||||
int x)
|
int x)
|
||||||
{
|
{
|
||||||
/* From GTK+ */
|
|
||||||
int thickness_light;
|
int thickness_light;
|
||||||
int thickness_dark;
|
int thickness_dark;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* From GTK+ */
|
||||||
|
|
||||||
thickness_light = 1;
|
thickness_light = 1;
|
||||||
thickness_dark = 1;
|
thickness_dark = 1;
|
||||||
@ -413,11 +440,56 @@ default_expose_frame (MetaFrameInfo *info,
|
|||||||
xoff = info->xoffset;
|
xoff = info->xoffset;
|
||||||
yoff = info->yoffset;
|
yoff = info->yoffset;
|
||||||
|
|
||||||
|
/* Black line around outside to give definition */
|
||||||
|
XDrawRectangle (info->display,
|
||||||
|
info->drawable,
|
||||||
|
screen_data->black_gc,
|
||||||
|
xoff, yoff,
|
||||||
|
info->width - 1,
|
||||||
|
info->height - 1);
|
||||||
|
|
||||||
|
/* Light GC on top/left edges */
|
||||||
|
XDrawLine (info->display,
|
||||||
|
info->drawable,
|
||||||
|
screen_data->light_gc,
|
||||||
|
xoff + 1, yoff + 1,
|
||||||
|
xoff + 1, yoff + info->height - 2);
|
||||||
|
XDrawLine (info->display,
|
||||||
|
info->drawable,
|
||||||
|
screen_data->light_gc,
|
||||||
|
xoff + 1, yoff + 1,
|
||||||
|
xoff + info->width - 2, yoff + 1);
|
||||||
|
|
||||||
|
/* Dark GC on bottom/right edges */
|
||||||
|
XDrawLine (info->display,
|
||||||
|
info->drawable,
|
||||||
|
screen_data->dark_gc,
|
||||||
|
xoff + info->width - 2, yoff + 1,
|
||||||
|
xoff + info->width - 2, yoff + info->height - 2);
|
||||||
|
XDrawLine (info->display,
|
||||||
|
info->drawable,
|
||||||
|
screen_data->dark_gc,
|
||||||
|
xoff + 1, yoff + info->height - 2,
|
||||||
|
xoff + info->width - 2, yoff + info->height - 2);
|
||||||
|
|
||||||
|
if (info->flags & META_FRAME_HAS_FOCUS)
|
||||||
|
{
|
||||||
|
/* Black line around inside while we have focus */
|
||||||
|
XDrawRectangle (info->display,
|
||||||
|
info->drawable,
|
||||||
|
screen_data->black_gc,
|
||||||
|
xoff + fgeom.left_width - 1,
|
||||||
|
yoff + fgeom.top_height - 1,
|
||||||
|
info->width - fgeom.right_width - fgeom.left_width + 1,
|
||||||
|
info->height - fgeom.bottom_height - fgeom.top_height + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (fgeom.title_rect.width > 0 && fgeom.title_rect.height > 0)
|
if (fgeom.title_rect.width > 0 && fgeom.title_rect.height > 0)
|
||||||
{
|
{
|
||||||
int layout_y;
|
int layout_y;
|
||||||
MetaRectangle clip;
|
MetaRectangle clip;
|
||||||
|
GC layout_gc;
|
||||||
|
|
||||||
/* center vertically */
|
/* center vertically */
|
||||||
layout_y = fgeom.title_rect.y +
|
layout_y = fgeom.title_rect.y +
|
||||||
(fgeom.title_rect.height - d->layout_height) / 2;
|
(fgeom.title_rect.height - d->layout_height) / 2;
|
||||||
@ -426,17 +498,28 @@ default_expose_frame (MetaFrameInfo *info,
|
|||||||
clip.x += xoff;
|
clip.x += xoff;
|
||||||
clip.y += yoff;
|
clip.y += yoff;
|
||||||
clip.width -= HORIZONTAL_TEXT_PAD;
|
clip.width -= HORIZONTAL_TEXT_PAD;
|
||||||
|
|
||||||
|
layout_gc = screen_data->text_gc;
|
||||||
|
|
||||||
set_clip (info->display, screen_data->text_gc, &clip);
|
|
||||||
if (info->flags & META_FRAME_HAS_FOCUS)
|
if (info->flags & META_FRAME_HAS_FOCUS)
|
||||||
{
|
{
|
||||||
/* FIXME use STATE_SELECTED */
|
layout_gc = screen_data->selected_text_gc;
|
||||||
|
|
||||||
|
/* Draw blue background */
|
||||||
|
XFillRectangle (info->display,
|
||||||
|
info->drawable,
|
||||||
|
screen_data->selected_gc,
|
||||||
|
xoff + fgeom.title_rect.x,
|
||||||
|
yoff + fgeom.title_rect.y,
|
||||||
|
fgeom.title_rect.width,
|
||||||
|
fgeom.title_rect.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_clip (info->display, layout_gc, &clip);
|
||||||
|
|
||||||
pango_x_render_layout (info->display,
|
pango_x_render_layout (info->display,
|
||||||
info->drawable,
|
info->drawable,
|
||||||
screen_data->text_gc,
|
layout_gc,
|
||||||
d->layout,
|
d->layout,
|
||||||
xoff + fgeom.title_rect.x + HORIZONTAL_TEXT_PAD,
|
xoff + fgeom.title_rect.x + HORIZONTAL_TEXT_PAD,
|
||||||
yoff + layout_y);
|
yoff + layout_y);
|
||||||
@ -580,6 +663,11 @@ default_release_screen (Screen *screen)
|
|||||||
{
|
{
|
||||||
XFreeGC (DisplayOfScreen (screen), screen_data->text_gc);
|
XFreeGC (DisplayOfScreen (screen), screen_data->text_gc);
|
||||||
XFreeGC (DisplayOfScreen (screen), screen_data->fg_gc);
|
XFreeGC (DisplayOfScreen (screen), screen_data->fg_gc);
|
||||||
|
XFreeGC (DisplayOfScreen (screen), screen_data->selected_gc);
|
||||||
|
XFreeGC (DisplayOfScreen (screen), screen_data->selected_text_gc);
|
||||||
|
XFreeGC (DisplayOfScreen (screen), screen_data->black_gc);
|
||||||
|
XFreeGC (DisplayOfScreen (screen), screen_data->light_gc);
|
||||||
|
XFreeGC (DisplayOfScreen (screen), screen_data->dark_gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
215
src/window.c
215
src/window.c
@ -33,6 +33,7 @@ static void constrain_size (MetaWindow *window,
|
|||||||
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 gboolean process_configure_request (MetaWindow *window,
|
static gboolean process_configure_request (MetaWindow *window,
|
||||||
int x, int y, int width, int height,
|
int x, int y, int width, int height,
|
||||||
int border_width);
|
int border_width);
|
||||||
@ -63,7 +64,13 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
|||||||
XAddToSaveSet (display->xdisplay, xwindow);
|
XAddToSaveSet (display->xdisplay, xwindow);
|
||||||
|
|
||||||
XSelectInput (display->xdisplay, xwindow,
|
XSelectInput (display->xdisplay, xwindow,
|
||||||
PropertyChangeMask);
|
PropertyChangeMask |
|
||||||
|
EnterWindowMask | LeaveWindowMask |
|
||||||
|
FocusChangeMask);
|
||||||
|
|
||||||
|
/* Get rid of any borders */
|
||||||
|
if (attrs.border_width != 0)
|
||||||
|
XSetWindowBorderWidth (display->xdisplay, xwindow, 0);
|
||||||
|
|
||||||
if (meta_error_trap_pop (display) != Success)
|
if (meta_error_trap_pop (display) != Success)
|
||||||
{
|
{
|
||||||
@ -96,12 +103,15 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_assert (window->screen);
|
g_assert (window->screen);
|
||||||
|
|
||||||
|
/* Remember this rect is the actual window size */
|
||||||
window->rect.x = attrs.x;
|
window->rect.x = attrs.x;
|
||||||
window->rect.y = attrs.y;
|
window->rect.y = attrs.y;
|
||||||
window->rect.width = attrs.width;
|
window->rect.width = attrs.width;
|
||||||
window->rect.height = attrs.height;
|
window->rect.height = attrs.height;
|
||||||
|
|
||||||
|
/* And border width, size_hints are the "request" */
|
||||||
|
window->border_width = attrs.border_width;
|
||||||
window->size_hints.x = attrs.x;
|
window->size_hints.x = attrs.x;
|
||||||
window->size_hints.y = attrs.y;
|
window->size_hints.y = attrs.y;
|
||||||
window->size_hints.width = attrs.width;
|
window->size_hints.width = attrs.width;
|
||||||
@ -116,13 +126,15 @@ meta_window_new (MetaDisplay *display, Window xwindow)
|
|||||||
window->desc = g_strdup_printf ("0x%lx", window->xwindow);
|
window->desc = g_strdup_printf ("0x%lx", window->xwindow);
|
||||||
|
|
||||||
window->frame = NULL;
|
window->frame = NULL;
|
||||||
|
window->has_focus = FALSE;
|
||||||
|
|
||||||
meta_display_register_x_window (display, &window->xwindow, window);
|
meta_display_register_x_window (display, &window->xwindow, window);
|
||||||
|
|
||||||
update_size_hints (window);
|
update_size_hints (window);
|
||||||
update_title (window);
|
update_title (window);
|
||||||
update_protocols (window);
|
update_protocols (window);
|
||||||
|
update_wm_hints (window);
|
||||||
|
|
||||||
meta_window_resize (window, window->size_hints.width, window->size_hints.height);
|
meta_window_resize (window, window->size_hints.width, window->size_hints.height);
|
||||||
|
|
||||||
meta_window_ensure_frame (window);
|
meta_window_ensure_frame (window);
|
||||||
@ -189,6 +201,82 @@ meta_window_resize (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_delete (MetaWindow *window,
|
||||||
|
Time timestamp)
|
||||||
|
{
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
meta_window_send_icccm_message (window,
|
||||||
|
window->display->atom_wm_delete_window,
|
||||||
|
timestamp);
|
||||||
|
meta_error_trap_pop (window->display);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_focus (MetaWindow *window,
|
||||||
|
Time timestamp)
|
||||||
|
{
|
||||||
|
meta_verbose ("Setting input focus to window %s, input: %d take_focus: %d\n",
|
||||||
|
window->desc, window->input, window->take_focus);
|
||||||
|
|
||||||
|
if (window->input)
|
||||||
|
{
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
if (window->take_focus)
|
||||||
|
{
|
||||||
|
meta_window_send_icccm_message (window,
|
||||||
|
window->display->atom_wm_take_focus,
|
||||||
|
timestamp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XSetInputFocus (window->display->xdisplay,
|
||||||
|
window->xwindow,
|
||||||
|
RevertToParent,
|
||||||
|
timestamp);
|
||||||
|
}
|
||||||
|
meta_error_trap_pop (window->display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_send_icccm_message (MetaWindow *window,
|
||||||
|
Atom atom,
|
||||||
|
Time timestamp)
|
||||||
|
{
|
||||||
|
/* This comment and code are from twm, copyright
|
||||||
|
* Open Group, Evans & Sutherland, etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ICCCM Client Messages - Section 4.2.8 of the ICCCM dictates that all
|
||||||
|
* client messages will have the following form:
|
||||||
|
*
|
||||||
|
* event type ClientMessage
|
||||||
|
* message type _XA_WM_PROTOCOLS
|
||||||
|
* window tmp->w
|
||||||
|
* format 32
|
||||||
|
* data[0] message atom
|
||||||
|
* data[1] time stamp
|
||||||
|
*/
|
||||||
|
|
||||||
|
XClientMessageEvent ev;
|
||||||
|
|
||||||
|
/* This should always be error trapped. */
|
||||||
|
g_return_if_fail (window->display->error_traps != NULL);
|
||||||
|
|
||||||
|
ev.type = ClientMessage;
|
||||||
|
ev.window = window->xwindow;
|
||||||
|
ev.message_type = window->display->atom_wm_protocols;
|
||||||
|
ev.format = 32;
|
||||||
|
ev.data.l[0] = atom;
|
||||||
|
ev.data.l[1] = timestamp;
|
||||||
|
|
||||||
|
XSendEvent (window->display->xdisplay,
|
||||||
|
window->xwindow, False, 0, (XEvent*) &ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_window_configure_request (MetaWindow *window,
|
meta_window_configure_request (MetaWindow *window,
|
||||||
XEvent *event)
|
XEvent *event)
|
||||||
@ -208,100 +296,6 @@ meta_window_property_notify (MetaWindow *window,
|
|||||||
return process_property_notify (window, &event->xproperty);
|
return process_property_notify (window, &event->xproperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
meta_window_event (MetaWindow *window,
|
|
||||||
XEvent *event)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (event->xany.window != window->xwindow)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
switch (event->type)
|
|
||||||
{
|
|
||||||
case KeyPress:
|
|
||||||
break;
|
|
||||||
case KeyRelease:
|
|
||||||
break;
|
|
||||||
case ButtonPress:
|
|
||||||
break;
|
|
||||||
case ButtonRelease:
|
|
||||||
break;
|
|
||||||
case MotionNotify:
|
|
||||||
break;
|
|
||||||
case EnterNotify:
|
|
||||||
break;
|
|
||||||
case LeaveNotify:
|
|
||||||
break;
|
|
||||||
case FocusIn:
|
|
||||||
break;
|
|
||||||
case FocusOut:
|
|
||||||
break;
|
|
||||||
case KeymapNotify:
|
|
||||||
break;
|
|
||||||
case Expose:
|
|
||||||
break;
|
|
||||||
case GraphicsExpose:
|
|
||||||
break;
|
|
||||||
case NoExpose:
|
|
||||||
break;
|
|
||||||
case VisibilityNotify:
|
|
||||||
break;
|
|
||||||
case CreateNotify:
|
|
||||||
break;
|
|
||||||
case DestroyNotify:
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
break;
|
|
||||||
case UnmapNotify:
|
|
||||||
/* Window withdrawn */
|
|
||||||
meta_window_free (window);
|
|
||||||
return TRUE;
|
|
||||||
break;
|
|
||||||
case MapNotify:
|
|
||||||
break;
|
|
||||||
case MapRequest:
|
|
||||||
break;
|
|
||||||
case ReparentNotify:
|
|
||||||
break;
|
|
||||||
case ConfigureNotify:
|
|
||||||
|
|
||||||
break;
|
|
||||||
case ConfigureRequest:
|
|
||||||
|
|
||||||
break;
|
|
||||||
case GravityNotify:
|
|
||||||
break;
|
|
||||||
case ResizeRequest:
|
|
||||||
break;
|
|
||||||
case CirculateNotify:
|
|
||||||
break;
|
|
||||||
case CirculateRequest:
|
|
||||||
break;
|
|
||||||
case PropertyNotify:
|
|
||||||
|
|
||||||
break;
|
|
||||||
case SelectionClear:
|
|
||||||
break;
|
|
||||||
case SelectionRequest:
|
|
||||||
break;
|
|
||||||
case SelectionNotify:
|
|
||||||
break;
|
|
||||||
case ColormapNotify:
|
|
||||||
break;
|
|
||||||
case ClientMessage:
|
|
||||||
break;
|
|
||||||
case MappingNotify:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Didn't use this event */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
process_property_notify (MetaWindow *window,
|
process_property_notify (MetaWindow *window,
|
||||||
XPropertyEvent *event)
|
XPropertyEvent *event)
|
||||||
@ -383,8 +377,7 @@ process_configure_request (MetaWindow *window,
|
|||||||
/* 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
|
||||||
* its border, but that we always deny border requests
|
* its border, but that we always deny border requests
|
||||||
* because we don't believe in clients who use lame-ass
|
* and give windows a border of 0
|
||||||
* X features like that.
|
|
||||||
*/
|
*/
|
||||||
window->border_width = border_width;
|
window->border_width = border_width;
|
||||||
|
|
||||||
@ -727,6 +720,30 @@ update_protocols (MetaWindow *window)
|
|||||||
return meta_error_trap_pop (window->display);
|
return meta_error_trap_pop (window->display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
update_wm_hints (MetaWindow *window)
|
||||||
|
{
|
||||||
|
XWMHints *hints;
|
||||||
|
|
||||||
|
/* Fill in defaults */
|
||||||
|
window->input = FALSE;
|
||||||
|
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
|
||||||
|
hints = XGetWMHints (window->display->xdisplay,
|
||||||
|
window->xwindow);
|
||||||
|
if (hints)
|
||||||
|
{
|
||||||
|
window->input = (hints->flags & InputHint) != 0;
|
||||||
|
|
||||||
|
/* FIXME there are a few others there. */
|
||||||
|
|
||||||
|
XFree (hints);
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
19
src/window.h
19
src/window.h
@ -41,7 +41,14 @@ struct _MetaWindow
|
|||||||
guint iconic : 1;
|
guint iconic : 1;
|
||||||
guint take_focus : 1;
|
guint take_focus : 1;
|
||||||
guint delete_window : 1;
|
guint delete_window : 1;
|
||||||
|
/* Globally active / No input */
|
||||||
|
guint input : 1;
|
||||||
|
|
||||||
|
/* this flag tracks receipt of focus_in focus_out and
|
||||||
|
* determines whether we draw the focus
|
||||||
|
*/
|
||||||
|
guint has_focus : 1;
|
||||||
|
|
||||||
/* The size we set the window to last. */
|
/* The size we set the window to last. */
|
||||||
MetaRectangle rect;
|
MetaRectangle rect;
|
||||||
|
|
||||||
@ -59,6 +66,16 @@ void meta_window_hide (MetaWindow *window);
|
|||||||
void meta_window_resize (MetaWindow *window,
|
void meta_window_resize (MetaWindow *window,
|
||||||
int w,
|
int w,
|
||||||
int h);
|
int h);
|
||||||
|
void meta_window_delete (MetaWindow *window,
|
||||||
|
Time timestamp);
|
||||||
|
void meta_window_focus (MetaWindow *window,
|
||||||
|
Time timestamp);
|
||||||
|
|
||||||
|
/* Sends a client message */
|
||||||
|
void meta_window_send_icccm_message (MetaWindow *window,
|
||||||
|
Atom atom,
|
||||||
|
Time timestamp);
|
||||||
|
|
||||||
|
|
||||||
gboolean meta_window_configure_request (MetaWindow *window,
|
gboolean meta_window_configure_request (MetaWindow *window,
|
||||||
XEvent *event);
|
XEvent *event);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user