From 1cd2915ba3dc15278392c3f6b5579e6a43aca962 Mon Sep 17 00:00:00 2001 From: rhp Date: Mon, 4 Jun 2001 04:58:22 +0000 Subject: [PATCH] ... --- src/display.c | 57 +++++++++--- src/display.h | 6 +- src/frame.c | 72 ++++++++++----- src/frame.h | 7 +- src/run-metacity.sh | 1 + src/theme.c | 126 ++++++++++++++++++++++---- src/window.c | 215 ++++++++++++++++++++++++-------------------- src/window.h | 19 +++- 8 files changed, 347 insertions(+), 156 deletions(-) diff --git a/src/display.c b/src/display.c index 037e43f0a..6215be61f 100644 --- a/src/display.c +++ b/src/display.c @@ -25,6 +25,7 @@ #include "screen.h" #include "window.h" #include "frame.h" +#include "errors.h" static GSList *all_displays = NULL; static void meta_spew_event (MetaDisplay *display, @@ -180,26 +181,24 @@ meta_display_close (MetaDisplay *display) g_hash_table_foreach (display->window_ids, listify_func, &winlist); - - g_hash_table_destroy (display->window_ids); winlist = g_slist_sort (winlist, ptrcmp); tmp = winlist; 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 || (tmp->next && tmp->next->data != tmp->data)) meta_window_free (tmp->data); - tmp = tmp->data; + tmp = tmp->next; } 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); XCloseDisplay (display->xdisplay); @@ -352,12 +351,34 @@ event_queue_callback (MetaEventQueue *queue, case MotionNotify: break; 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; case LeaveNotify: break; 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; 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; case KeymapNotify: break; @@ -470,8 +491,6 @@ event_get_modified_window (MetaDisplay *display, case ButtonPress: case ButtonRelease: case MotionNotify: - case EnterNotify: - case LeaveNotify: case FocusIn: case FocusOut: case KeymapNotify: @@ -486,8 +505,10 @@ event_get_modified_window (MetaDisplay *display, case SelectionNotify: case ColormapNotify: case ClientMessage: + case EnterNotify: + case LeaveNotify: return event->xany.window; - + case CreateNotify: return event->xcreatewindow.window; @@ -558,9 +579,21 @@ meta_spew_event (MetaDisplay *display, break; case 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; case 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; case FocusIn: name = "FocusIn"; diff --git a/src/display.h b/src/display.h index 681e7619c..8933d1647 100644 --- a/src/display.h +++ b/src/display.h @@ -42,6 +42,11 @@ struct _MetaDisplay Atom atom_wm_protocols; Atom atom_wm_take_focus; Atom atom_wm_delete_window; + + /* This is the actual window from focus events, + * not the one we last set + */ + MetaWindow *focus_window; /*< private-ish >*/ MetaEventQueue *events; @@ -61,7 +66,6 @@ void meta_display_grab (MetaDisplay *display); void meta_display_ungrab (MetaDisplay *display); PangoContext* meta_display_get_pango_context (MetaDisplay *display); - /* A given MetaWindow may have various X windows that "belong" * to it, such as the frame window. */ diff --git a/src/frame.c b/src/frame.c index 431e66d25..20e9202a6 100644 --- a/src/frame.c +++ b/src/frame.c @@ -32,6 +32,9 @@ meta_frame_init_info (MetaFrame *frame, META_FRAME_ALLOWS_DELETE | META_FRAME_ALLOWS_MENU | META_FRAME_ALLOWS_ICONIFY | META_FRAME_ALLOWS_MAXIMIZE | META_FRAME_ALLOWS_RESIZE; + + if (frame->window->has_focus) + info->flags |= META_FRAME_HAS_FOCUS; info->drawable = None; 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.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; @@ -157,6 +163,18 @@ set_background_none (MetaFrame *frame) frame->xwindow, CWBackPixmap, &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 @@ -211,8 +229,9 @@ meta_window_ensure_frame (MetaWindow *window) attrs.background_pixel = frame->bg_pixel; attrs.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask | - ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask | - PointerMotionMask | PointerMotionHintMask; + ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | PointerMotionHintMask | + EnterWindowMask | LeaveWindowMask; frame->xwindow = XCreateWindow (window->display->xdisplay, window->screen->xroot, @@ -230,9 +249,6 @@ meta_window_ensure_frame (MetaWindow *window) meta_verbose ("Frame is 0x%lx\n", frame->xwindow); 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); @@ -502,31 +518,32 @@ static void update_move (MetaFrame *frame) { int x, y; - int new_x, new_y; + int dx, dy; + frame_query_root_pointer (frame, &x, &y); - new_x = frame->rect.x + (x - frame->last_x); - new_y = frame->rect.y + (y - frame->last_y); - frame->last_x = x; - frame->last_y = y; + dx = x - frame->start_root_x; + dy = y - frame->start_root_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 update_resize_se (MetaFrame *frame) { int x, y; - int new_w, new_h; - + int dx, dy; + frame_query_root_pointer (frame, &x, &y); - new_w = frame->window->rect.width + (x - frame->last_x); - new_h = frame->window->rect.height + (y - frame->last_y); - frame->last_x = x; - frame->last_y = y; + dx = x - frame->start_root_x; + dy = y - frame->start_root_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 @@ -555,8 +572,10 @@ meta_frame_event (MetaFrame *frame, meta_verbose ("Begin move on %s\n", frame->window->desc); frame->action = META_FRAME_ACTION_MOVING; - frame->last_x = event->xbutton.x_root; - frame->last_y = event->xbutton.y_root; + frame->start_root_x = event->xbutton.x_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; } else if (control == META_FRAME_CONTROL_DELETE && @@ -565,6 +584,7 @@ meta_frame_event (MetaFrame *frame, /* FIXME delete event */ meta_verbose ("Close control clicked on %s\n", frame->window->desc); + meta_window_delete (frame->window, event->xbutton.time); } else if (control == META_FRAME_CONTROL_RESIZE_SE && event->xbutton.button == 1) @@ -572,8 +592,10 @@ meta_frame_event (MetaFrame *frame, meta_verbose ("Resize control clicked on %s\n", frame->window->desc); frame->action = META_FRAME_ACTION_RESIZING_SE; - frame->last_x = event->xbutton.x_root; - frame->last_y = event->xbutton.y_root; + frame->start_root_x = event->xbutton.x_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; } } @@ -622,6 +644,12 @@ meta_frame_event (MetaFrame *frame, } break; 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; case LeaveNotify: break; diff --git a/src/frame.h b/src/frame.h index cea1bb2ab..0757d7a0c 100644 --- a/src/frame.h +++ b/src/frame.h @@ -50,8 +50,11 @@ struct _MetaFrame gulong bg_pixel; MetaFrameAction action; - /* reference point for drags */ - int last_x, last_y; + /* initial mouse position for drags */ + 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; guint theme_acquired : 1; diff --git a/src/run-metacity.sh b/src/run-metacity.sh index f1ed6afdd..40ef0d418 100755 --- a/src/run-metacity.sh +++ b/src/run-metacity.sh @@ -10,5 +10,6 @@ elif test -z "$DEBUG"; then fi Xnest :1 -scrns $SCREENS -geometry 270x270 & +DISPLAY=:1 xsetroot -solid royalblue3 METACITY_UISLAVE_DIR=./uislave DISPLAY=:1 unst libtool --mode=execute $DEBUG ./metacity killall Xnest diff --git a/src/theme.c b/src/theme.c index 58561385c..2db9c513e 100644 --- a/src/theme.c +++ b/src/theme.c @@ -55,6 +55,9 @@ struct _DefaultScreenData GC fg_gc; GC light_gc; GC dark_gc; + GC black_gc; + GC selected_gc; + GC selected_text_gc; }; /* FIXME store this on the screen */ @@ -69,13 +72,13 @@ default_acquire_frame (MetaFrameInfo *info) if (screen_data == NULL) { + PangoColor color; + screen_data = g_new (DefaultScreenData, 1); vals.foreground = meta_get_x_pixel (info->screen, &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, RootWindowOfScreen (info->screen), GCForeground, @@ -98,6 +101,27 @@ default_acquire_frame (MetaFrameInfo *info) RootWindowOfScreen (info->screen), GCForeground, &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); @@ -126,13 +150,15 @@ default_release_frame (MetaFrameInfo *info, g_free (d); } -#define VERTICAL_TITLE_PAD 2 -#define HORIZONTAL_TITLE_PAD 3 +#define ABOVE_TITLE_PAD 4 +#define BELOW_TITLE_PAD 3 +#define RIGHT_TITLE_PAD 4 +#define LEFT_TITLE_PAD 3 #define VERTICAL_TEXT_PAD 2 #define HORIZONTAL_TEXT_PAD 2 -#define LEFT_WIDTH 2 -#define RIGHT_WIDTH 2 -#define BOTTOM_HEIGHT 5 +#define LEFT_WIDTH 6 +#define RIGHT_WIDTH 6 +#define BOTTOM_HEIGHT 7 #define SPACER_SPACING 3 #define SPACER_WIDTH 2 #define SPACER_HEIGHT 10 @@ -149,7 +175,7 @@ calc_geometry (MetaFrameInfo *info, int button_y; 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); fgeom->left_width = LEFT_WIDTH; @@ -229,7 +255,7 @@ calc_geometry (MetaFrameInfo *info, 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 */ x = fgeom->left_width; @@ -251,10 +277,10 @@ calc_geometry (MetaFrameInfo *info, fgeom->menu_rect.height = 0; } - fgeom->title_rect.x = x + BUTTON_PAD; - fgeom->title_rect.y = VERTICAL_TITLE_PAD; + fgeom->title_rect.x = x + LEFT_TITLE_PAD; + fgeom->title_rect.y = ABOVE_TITLE_PAD; 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) fgeom->title_rect.width = 0; @@ -299,10 +325,11 @@ draw_vline (MetaFrameInfo *info, int y2, int x) { - /* From GTK+ */ int thickness_light; int thickness_dark; int i; + + /* From GTK+ */ thickness_light = 1; thickness_dark = 1; @@ -413,11 +440,56 @@ default_expose_frame (MetaFrameInfo *info, xoff = info->xoffset; 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) { int layout_y; MetaRectangle clip; - + GC layout_gc; + /* center vertically */ layout_y = fgeom.title_rect.y + (fgeom.title_rect.height - d->layout_height) / 2; @@ -426,17 +498,28 @@ default_expose_frame (MetaFrameInfo *info, clip.x += xoff; clip.y += yoff; 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) { - /* 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, info->drawable, - screen_data->text_gc, + layout_gc, d->layout, xoff + fgeom.title_rect.x + HORIZONTAL_TEXT_PAD, yoff + layout_y); @@ -580,6 +663,11 @@ default_release_screen (Screen *screen) { XFreeGC (DisplayOfScreen (screen), screen_data->text_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); } } diff --git a/src/window.c b/src/window.c index ed2b2e1cd..c4ad7f0c7 100644 --- a/src/window.c +++ b/src/window.c @@ -33,6 +33,7 @@ static void constrain_size (MetaWindow *window, 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 gboolean process_configure_request (MetaWindow *window, int x, int y, int width, int height, int border_width); @@ -63,7 +64,13 @@ meta_window_new (MetaDisplay *display, Window xwindow) XAddToSaveSet (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) { @@ -96,12 +103,15 @@ meta_window_new (MetaDisplay *display, Window xwindow) } g_assert (window->screen); - + + /* Remember this rect is the actual window size */ window->rect.x = attrs.x; window->rect.y = attrs.y; window->rect.width = attrs.width; 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.y = attrs.y; 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->frame = NULL; + window->has_focus = FALSE; meta_display_register_x_window (display, &window->xwindow, window); update_size_hints (window); update_title (window); update_protocols (window); - + update_wm_hints (window); + meta_window_resize (window, window->size_hints.width, window->size_hints.height); 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 meta_window_configure_request (MetaWindow *window, XEvent *event) @@ -208,100 +296,6 @@ meta_window_property_notify (MetaWindow *window, 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 process_property_notify (MetaWindow *window, XPropertyEvent *event) @@ -383,8 +377,7 @@ process_configure_request (MetaWindow *window, /* Note that x, y is the corner of the window border, * and width, height is the size of the window inside * its border, but that we always deny border requests - * because we don't believe in clients who use lame-ass - * X features like that. + * and give windows a border of 0 */ window->border_width = border_width; @@ -727,6 +720,30 @@ update_protocols (MetaWindow *window) 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 constrain_size (MetaWindow *window, int width, int height, diff --git a/src/window.h b/src/window.h index 01f68bd5c..2d258cdf6 100644 --- a/src/window.h +++ b/src/window.h @@ -41,7 +41,14 @@ struct _MetaWindow guint iconic : 1; guint take_focus : 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. */ MetaRectangle rect; @@ -59,6 +66,16 @@ void meta_window_hide (MetaWindow *window); void meta_window_resize (MetaWindow *window, int w, 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, XEvent *event);