diff --git a/src/core.c b/src/core.c index 7bf68bb32..89ea0e9f3 100644 --- a/src/core.c +++ b/src/core.c @@ -70,9 +70,8 @@ meta_core_queue_frame_resize (Display *xdisplay, window = meta_display_lookup_x_window (display, frame_xwindow); if (window == NULL || window->frame == NULL) - meta_bug ("No such frame window 0x%lx!\n", frame_xwindow); - + meta_bug ("No such frame window 0x%lx!\n", frame_xwindow); - g_warning ("FIXME"); + meta_window_queue_move_resize (window); } diff --git a/src/display.c b/src/display.c index cd6e39097..b71b48291 100644 --- a/src/display.c +++ b/src/display.c @@ -31,11 +31,14 @@ #include #include +#define USE_GDK_DISPLAY + static GSList *all_displays = NULL; static void meta_spew_event (MetaDisplay *display, XEvent *event); -static void event_queue_callback (MetaEventQueue *queue, - XEvent *event, +static void event_queue_callback (XEvent *event, + gpointer data); +static gboolean event_callback (XEvent *event, gpointer data); static Window event_get_modified_window (MetaDisplay *display, XEvent *event); @@ -126,9 +129,13 @@ meta_display_open (const char *name) Atom atoms[G_N_ELEMENTS(atom_names)]; meta_verbose ("Opening display '%s'\n", XDisplayName (name)); - - xdisplay = XOpenDisplay (name); +#ifdef USE_GDK_DISPLAY + xdisplay = meta_ui_get_display (name); +#else + xdisplay = XOpenDisplay (name); +#endif + if (xdisplay == NULL) { meta_warning (_("Failed to open X Window System display '%s'\n"), @@ -225,7 +232,9 @@ meta_display_open (const char *name) /* This would typically happen because all the screens already * have window managers */ +#ifndef USE_GDK_DISPLAY XCloseDisplay (xdisplay); +#endif all_displays = g_slist_remove (all_displays, display); g_free (display->name); g_free (display); @@ -233,11 +242,20 @@ meta_display_open (const char *name) } display->screens = screens; - + +#ifdef USE_GDK_DISPLAY + display->events = NULL; + + /* Get events */ + meta_ui_add_event_func (display->xdisplay, + event_callback, + display); +#else display->events = meta_event_queue_new (display->xdisplay, event_queue_callback, display); - +#endif + display->window_ids = g_hash_table_new (unsigned_long_hash, unsigned_long_equal); display->double_click_time = 250; @@ -312,6 +330,13 @@ meta_display_close (MetaDisplay *display) g_slist_free (winlist); meta_display_ungrab (display); +#ifdef USE_GDK_DISPLAY + /* Stop caring about events */ + meta_ui_remove_event_func (display->xdisplay, + event_callback, + display); +#endif + /* Must be after all calls to meta_window_free() since they * unregister windows */ @@ -319,9 +344,11 @@ meta_display_close (MetaDisplay *display) if (display->leader_window != None) XDestroyWindow (display->xdisplay, display->leader_window); - + +#ifndef USE_GDK_DISPLAY meta_event_queue_free (display->events); XCloseDisplay (display->xdisplay); +#endif g_free (display->name); all_displays = g_slist_remove (all_displays, display); @@ -444,10 +471,17 @@ meta_display_is_double_click (MetaDisplay *display) static gboolean dump_events = TRUE; + static void -event_queue_callback (MetaEventQueue *queue, - XEvent *event, +event_queue_callback (XEvent *event, gpointer data) +{ + event_callback (event, data); +} + +static gboolean +event_callback (XEvent *event, + gpointer data) { MetaWindow *window; MetaDisplay *display; @@ -457,7 +491,7 @@ event_queue_callback (MetaEventQueue *queue, if (dump_events) meta_spew_event (display, event); - + /* mark double click events, kind of a hack, oh well. */ if (event->type == ButtonPress) { @@ -490,7 +524,7 @@ event_queue_callback (MetaEventQueue *queue, modified == window->frame->xwindow) { meta_frame_event (window->frame, event); - return; + return FALSE; } switch (event->type) @@ -677,6 +711,8 @@ event_queue_callback (MetaEventQueue *queue, default: break; } + + return FALSE; } /* Return the window this has to do with, if any, rather diff --git a/src/eventqueue.c b/src/eventqueue.c index 11c1dc9a8..243b12ee9 100644 --- a/src/eventqueue.c +++ b/src/eventqueue.c @@ -151,7 +151,7 @@ eq_dispatch (GSource *source, GSourceFunc callback, gpointer user_data) event = g_queue_pop_head (eq->events); func = (MetaEventQueueFunc) callback; - (* func) (eq, event, user_data); + (* func) (event, user_data); g_free (event); } diff --git a/src/eventqueue.h b/src/eventqueue.h index 10f0fbc42..0e256fc07 100644 --- a/src/eventqueue.h +++ b/src/eventqueue.h @@ -27,8 +27,7 @@ typedef struct _MetaEventQueue MetaEventQueue; -typedef void (* MetaEventQueueFunc) (MetaEventQueue *queue, - XEvent *event, +typedef void (* MetaEventQueueFunc) (XEvent *event, gpointer data); MetaEventQueue* meta_event_queue_new (Display *display, diff --git a/src/frame.c b/src/frame.c index dfa050bfa..f7acb261f 100644 --- a/src/frame.c +++ b/src/frame.c @@ -22,6 +22,13 @@ #include "frame.h" #include "errors.h" +#define EVENT_MASK (SubstructureRedirectMask | \ + StructureNotifyMask | SubstructureNotifyMask | \ + ExposureMask | \ + ButtonPressMask | ButtonReleaseMask | \ + PointerMotionMask | PointerMotionHintMask | \ + EnterWindowMask | LeaveWindowMask) + void meta_window_ensure_frame (MetaWindow *window) { @@ -46,9 +53,7 @@ meta_window_ensure_frame (MetaWindow *window) frame->mapped = FALSE; - attrs.event_mask = SubstructureRedirectMask | - StructureNotifyMask | SubstructureNotifyMask | - EnterWindowMask | LeaveWindowMask; + attrs.event_mask = EVENT_MASK; frame->xwindow = XCreateWindow (window->display->xdisplay, window->screen->xroot, @@ -92,10 +97,15 @@ meta_window_ensure_frame (MetaWindow *window) window->rect.y); meta_error_trap_pop (window->display); - meta_ui_add_frame (window->screen->ui, frame->xwindow); - /* stick frame to the window */ window->frame = frame; + + meta_ui_add_frame (window->screen->ui, frame->xwindow); + + if (window->title) + meta_ui_set_frame_title (window->screen->ui, + window->frame->xwindow, + window->title); } void diff --git a/src/frames.c b/src/frames.c index 80e3fa0c3..9b05b13ff 100644 --- a/src/frames.c +++ b/src/frames.c @@ -34,17 +34,6 @@ struct _MetaFrameActionGrab /* button doing the dragging */ int start_button; }; - - -/* This lacks ButtonReleaseMask to avoid the auto-grab - * since it breaks our popup menu - */ -#define EVENT_MASK (SubstructureRedirectMask | \ - StructureNotifyMask | SubstructureNotifyMask | \ - ExposureMask | \ - ButtonPressMask | ButtonReleaseMask | \ - PointerMotionMask | PointerMotionHintMask | \ - EnterWindowMask | LeaveWindowMask) #endif struct _MetaUIFrame @@ -232,7 +221,7 @@ meta_frames_get_type (void) (GtkClassInitFunc) NULL, }; - frames_type = gtk_type_unique (GTK_TYPE_WIDGET, &frames_info); + frames_type = gtk_type_unique (GTK_TYPE_WINDOW, &frames_info); } return frames_type; @@ -494,7 +483,7 @@ meta_frames_style_set (GtkWidget *widget, g_object_unref (G_OBJECT (font)); - frames->text_height = metrics.ascent + metrics.descent; + frames->text_height = PANGO_PIXELS (metrics.ascent + metrics.descent); } /* Queue a draw/resize on all frames */ @@ -694,7 +683,9 @@ meta_frames_manage_window (MetaFrames *frames, } gdk_window_set_user_data (frame->window, frames); - + +#if 0 + /* Add events in frame.c */ gdk_window_set_events (frame->window, GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | @@ -702,7 +693,8 @@ meta_frames_manage_window (MetaFrames *frames, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK); - +#endif + /* This shouldn't be required if we don't select for button * press in frame.c? */ @@ -1025,13 +1017,16 @@ meta_frames_expose_event (GtkWidget *widget, fgeom.title_rect.height); } - gdk_gc_set_clip_rectangle (layout_gc, &clip); - gdk_draw_layout (frame->window, - layout_gc, - fgeom.title_rect.x + frames->props->text_border.left, - fgeom.title_rect.y + frames->props->text_border.top, - frame->layout); - gdk_gc_set_clip_rectangle (layout_gc, NULL); + if (frame->layout) + { + gdk_gc_set_clip_rectangle (layout_gc, &clip); + gdk_draw_layout (frame->window, + layout_gc, + fgeom.title_rect.x + frames->props->text_border.left, + fgeom.title_rect.y + frames->props->text_border.top, + frame->layout); + gdk_gc_set_clip_rectangle (layout_gc, NULL); + } } inner = frames->props->inner_button_border; diff --git a/src/main.c b/src/main.c index 68defa8fc..5fe6218a8 100644 --- a/src/main.c +++ b/src/main.c @@ -25,7 +25,7 @@ #include "errors.h" #include "ui.h" -#include +#include #include #include diff --git a/src/run-metacity.sh b/src/run-metacity.sh index 611d94a7a..abd08f34a 100755 --- a/src/run-metacity.sh +++ b/src/run-metacity.sh @@ -14,7 +14,7 @@ if test -z "$CLIENTS"; then fi if test -z "$ONLY_WM"; then - Xnest :1 -scrns $SCREENS -geometry 640x480 -bw 15 & + Xnest -ac :1 -scrns $SCREENS -geometry 640x480 -bw 15 & usleep 50000 if test $CLIENTS != 0; then diff --git a/src/screen.c b/src/screen.c index 778e9cb2f..a9c00b6e6 100644 --- a/src/screen.c +++ b/src/screen.c @@ -349,6 +349,17 @@ meta_screen_queue_frame_redraws (MetaScreen *screen) meta_screen_foreach_window (screen, queue_draw, NULL); } +static void +queue_resize (MetaScreen *screen, MetaWindow *window, gpointer data) +{ + meta_window_queue_move_resize (window); +} + +void +meta_screen_queue_window_resizes (MetaScreen *screen) +{ + meta_screen_foreach_window (screen, queue_resize, NULL); +} int meta_screen_get_n_workspaces (MetaScreen *screen) diff --git a/src/screen.h b/src/screen.h index 0ac1c743c..6879e6e53 100644 --- a/src/screen.h +++ b/src/screen.h @@ -52,6 +52,7 @@ void meta_screen_foreach_window (MetaScreen *scree MetaScreenWindowFunc func, gpointer data); void meta_screen_queue_frame_redraws (MetaScreen *screen); +void meta_screen_queue_window_resizes (MetaScreen *screen); int meta_screen_get_n_workspaces (MetaScreen *screen); diff --git a/src/ui.c b/src/ui.c index a897573c0..791676683 100644 --- a/src/ui.c +++ b/src/ui.c @@ -37,6 +37,68 @@ meta_ui_init (int *argc, char ***argv) meta_fatal ("Unable to open X display %s\n", gdk_display_name); } +Display* +meta_ui_get_display (const char *name) +{ + if (name == NULL) + return gdk_display; + else + return NULL; +} + +typedef struct _EventFunc EventFunc; + +struct _EventFunc +{ + MetaEventFunc func; + gpointer data; +}; + +static GdkFilterReturn +filter_func (GdkXEvent *xevent, + GdkEvent *event, + gpointer data) +{ + EventFunc *ef; + + ef = data; + + if ((* ef->func) (xevent, ef->data)) + return GDK_FILTER_REMOVE; + else + return GDK_FILTER_CONTINUE; +} + +static EventFunc *ef = NULL; + +void +meta_ui_add_event_func (Display *xdisplay, + MetaEventFunc func, + gpointer data) +{ + g_return_if_fail (ef == NULL); + + ef = g_new (EventFunc, 1); + ef->func = func; + ef->data = data; + + gdk_window_add_filter (NULL, filter_func, ef); +} + +/* removal is by data due to proxy function */ +void +meta_ui_remove_event_func (Display *xdisplay, + MetaEventFunc func, + gpointer data) +{ + g_return_if_fail (ef != NULL); + + gdk_window_remove_filter (NULL, filter_func, ef); + + g_free (ef); + ef = NULL; +} + MetaUI* meta_ui_new (Display *xdisplay, Screen *screen) @@ -88,6 +150,30 @@ meta_ui_remove_frame (MetaUI *ui, meta_frames_unmanage_window (ui->frames, xwindow); } +void +meta_ui_map_frame (MetaUI *ui, + Window xwindow) +{ + GdkWindow *window; + + window = gdk_xid_table_lookup (xwindow); + + if (window) + gdk_x11_window_map (window); +} + +void +meta_ui_unmap_frame (MetaUI *ui, + Window xwindow) +{ + GdkWindow *window; + + window = gdk_xid_table_lookup (xwindow); + + if (window) + gdk_window_hide (window); +} + void meta_ui_reset_frame_bg (MetaUI *ui, Window xwindow) @@ -103,4 +189,12 @@ meta_ui_queue_frame_draw (MetaUI *ui, } +void +meta_ui_set_frame_title (MetaUI *ui, + Window xwindow, + const char *title) +{ + meta_frames_set_title (ui->frames, xwindow, title); +} + diff --git a/src/ui.h b/src/ui.h index 240872f43..b30b2f3fa 100644 --- a/src/ui.h +++ b/src/ui.h @@ -24,11 +24,24 @@ /* Don't include gtk.h here */ #include "common.h" +#include +#include typedef struct _MetaUI MetaUI; +typedef gboolean (* MetaEventFunc) (XEvent *xevent, gpointer data); + void meta_ui_init (int *argc, char ***argv); +Display* meta_ui_get_display (const char *name); + +void meta_ui_add_event_func (Display *xdisplay, + MetaEventFunc func, + gpointer data); +void meta_ui_remove_event_func (Display *xdisplay, + MetaEventFunc func, + gpointer data); + MetaUI* meta_ui_new (Display *xdisplay, Screen *screen); void meta_ui_free (MetaUI *ui); @@ -42,6 +55,11 @@ void meta_ui_add_frame (MetaUI *ui, void meta_ui_remove_frame (MetaUI *ui, Window xwindow); +/* GDK insists on tracking map/unmap */ +void meta_ui_map_frame (MetaUI *ui, + Window xwindow); +void meta_ui_unmap_frame (MetaUI *ui, + Window xwindow); void meta_ui_reset_frame_bg (MetaUI *ui, Window xwindow); @@ -49,4 +67,8 @@ void meta_ui_reset_frame_bg (MetaUI *ui, void meta_ui_queue_frame_draw (MetaUI *ui, Window xwindow); +void meta_ui_set_frame_title (MetaUI *ui, + Window xwindow, + const char *title); + #endif diff --git a/src/window.c b/src/window.c index 26b3706b4..f323ebacf 100644 --- a/src/window.c +++ b/src/window.c @@ -479,7 +479,7 @@ meta_window_show (MetaWindow *window) { meta_verbose ("Frame actually needs map\n"); window->frame->mapped = TRUE; - XMapWindow (window->display->xdisplay, window->frame->xwindow); + meta_ui_map_frame (window->screen->ui, window->frame->xwindow); } if (window->shaded) @@ -528,7 +528,7 @@ meta_window_hide (MetaWindow *window) { meta_verbose ("Frame actually needs unmap\n"); window->frame->mapped = FALSE; - XUnmapWindow (window->display->xdisplay, window->frame->xwindow); + meta_ui_unmap_frame (window->screen->ui, window->frame->xwindow); } if (window->mapped) @@ -1422,8 +1422,6 @@ process_property_notify (MetaWindow *window, event->atom == window->display->atom_net_wm_name) { update_title (window); - - meta_window_queue_move_resize (window); } else if (event->atom == XA_WM_NORMAL_HINTS) { @@ -1788,6 +1786,11 @@ update_title (MetaWindow *window) g_free (window->desc); window->desc = g_strdup_printf ("0x%lx (%.10s)", window->xwindow, window->title); + + if (window->frame) + meta_ui_set_frame_title (window->screen->ui, + window->frame->xwindow, + window->title); return meta_error_trap_pop (window->display); }