summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrhp <rhp>2001-06-18 03:24:25 +0000
committerrhp <rhp>2001-06-18 03:24:25 +0000
commitd090d9f284e27aee37062c0e2f926075dc5b9a06 (patch)
tree13e71f3f64e7c0e7f5cbf352907f7a1d7e4bf20c
parent59513231a57cba1c67ed574a660cc19e3ace9922 (diff)
downloadmutter-d090d9f284e27aee37062c0e2f926075dc5b9a06.tar.gz
...
-rw-r--r--src/common.h41
-rw-r--r--src/core.c38
-rw-r--r--src/core.h9
-rw-r--r--src/display.h1
-rw-r--r--src/frame.c858
-rw-r--r--src/frame.h40
-rw-r--r--src/frames.c765
-rw-r--r--src/frames.h35
-rw-r--r--src/screen.c43
-rw-r--r--src/screen.h3
-rw-r--r--src/ui.c84
-rw-r--r--src/ui.h22
-rw-r--r--src/window.c2
13 files changed, 1058 insertions, 883 deletions
diff --git a/src/common.h b/src/common.h
new file mode 100644
index 000000000..920856901
--- /dev/null
+++ b/src/common.h
@@ -0,0 +1,41 @@
+/* Metacity common types shared by core.h and ui.h */
+
+/*
+ * 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_COMMON_H
+#define META_COMMON_H
+
+/* Don't include GTK or core headers here */
+#include <X11/Xlib.h>
+
+typedef enum
+{
+ META_FRAME_ALLOWS_DELETE = 1 << 0,
+ META_FRAME_ALLOWS_MENU = 1 << 1,
+ META_FRAME_ALLOWS_MINIMIZE = 1 << 2,
+ META_FRAME_ALLOWS_MAXIMIZE = 1 << 3,
+ META_FRAME_ALLOWS_RESIZE = 1 << 4,
+ META_FRAME_TRANSIENT = 1 << 5,
+ META_FRAME_HAS_FOCUS = 1 << 6,
+ META_FRAME_SHADED = 1 << 7,
+ META_FRAME_STUCK = 1 << 8
+} MetaFrameFlags;
+
+#endif
diff --git a/src/core.c b/src/core.c
index 0c935d9ab..8d07ba2bb 100644
--- a/src/core.c
+++ b/src/core.c
@@ -20,4 +20,42 @@
*/
#include "core.h"
+#include "display.h"
+void
+meta_core_get_frame_size (Display *xdisplay,
+ Window frame_xwindow,
+ int *width,
+ int *height)
+{
+ MetaDisplay *display;
+ MetaWindow *window;
+
+ display = meta_display_for_x_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);
+
+ if (width)
+ *width = window->frame->rect.width;
+ if (height)
+ *height = window->frame->rect.height;
+}
+
+void
+meta_core_get_frame_flags (Display *xdisplay,
+ Window frame_xwindow,
+ MetaFrameFlags flags)
+{
+ MetaDisplay *display;
+ MetaWindow *window;
+
+ display = meta_display_for_x_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);
+
+ return meta_frame_get_flags (window->frame);
+}
diff --git a/src/core.h b/src/core.h
index f49372f9d..124a1edf8 100644
--- a/src/core.h
+++ b/src/core.h
@@ -26,6 +26,15 @@
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include "frames.h"
+#include "common.h"
+void meta_core_get_frame_size (Display *xdisplay,
+ Window frame_xwindow,
+ int *width,
+ int *height);
+
+void meta_core_get_frame_flags (Display *xdisplay,
+ Window frame_xwindow,
+ MetaFrameFlags flags);
#endif
diff --git a/src/display.h b/src/display.h
index eaf615bbb..8a2924c24 100644
--- a/src/display.h
+++ b/src/display.h
@@ -24,7 +24,6 @@
#include <glib.h>
#include <X11/Xlib.h>
-#include <pango/pangox.h>
#include "eventqueue.h"
typedef struct _MetaDisplay MetaDisplay;
diff --git a/src/frame.c b/src/frame.c
index f8efb9f91..02c9332d5 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -22,165 +22,6 @@
#include "frame.h"
#include "errors.h"
#include "uislave.h"
-#include "colors.h"
-
-struct _MetaFrameActionGrab
-{
- MetaFrameAction action;
- /* 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;
-};
-
-/* 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)
-
-static void clear_tip (MetaFrame *frame);
-
-static guint draw_handler = 0;
-static GSList *draw_pending = NULL;
-
-static void
-meta_frame_init_info (MetaFrame *frame,
- MetaFrameInfo *info)
-{
- info->flags =
- META_FRAME_ALLOWS_MENU | META_FRAME_ALLOWS_RESIZE;
-
- if (frame->window->has_close_func)
- info->flags |= META_FRAME_ALLOWS_DELETE;
-
- if (frame->window->type == META_WINDOW_NORMAL)
- info->flags |= (META_FRAME_ALLOWS_ICONIFY | META_FRAME_ALLOWS_MAXIMIZE);
-
- if (!frame->window->has_maximize_func)
- info->flags &= ~META_FRAME_ALLOWS_MAXIMIZE;
-
- if (!frame->window->has_minimize_func)
- info->flags &= ~META_FRAME_ALLOWS_ICONIFY;
-
- if (frame->window->has_focus)
- info->flags |= META_FRAME_HAS_FOCUS;
-
- if (frame->window->shaded)
- info->flags |= META_FRAME_SHADED;
-
- if (frame->window->on_all_workspaces)
- info->flags |= META_FRAME_STUCK;
-
- info->drawable = None;
- info->xoffset = 0;
- info->yoffset = 0;
- info->display = frame->window->display->xdisplay;
- info->screen = frame->window->screen->xscreen;
- info->visual = frame->window->xvisual;
- info->depth = frame->window->depth;
- info->title = frame->window->title;
- info->width = frame->rect.width;
- info->height = frame->rect.height;
- info->colors = &(frame->window->screen->colors);
- info->current_control = frame->current_control;
- if (frame->grab)
- info->current_control_state = META_STATE_ACTIVE;
- else
- info->current_control_state = META_STATE_PRELIGHT;
-}
-
-void
-meta_frame_calc_geometry (MetaFrame *frame,
- int child_width, int child_height,
- MetaFrameGeometry *geomp)
-{
- MetaFrameInfo info;
- MetaFrameGeometry geom;
- MetaWindow *window;
-
- /* Remember this is called from the constructor
- * pre-X-window-creation.
- */
-
- window = frame->window;
-
- /* 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);
- frame->theme_acquired = TRUE;
- }
-
- geom.left_width = 0;
- geom.right_width = 0;
- geom.top_height = 0;
- geom.bottom_height = 0;
- geom.background_pixel =
- meta_screen_get_x_pixel (frame->window->screen,
- &frame->window->screen->colors.bg[META_STATE_NORMAL]);
-
- geom.shape_mask = None;
-
- window->screen->engine->fill_frame_geometry (&info, &geom,
- frame->theme_data);
-
- *geomp = geom;
-}
-
-static void
-set_background_none (MetaFrame *frame)
-{
- XSetWindowAttributes attrs;
-
- attrs.background_pixmap = None;
- XChangeWindowAttributes (frame->window->display->xdisplay,
- frame->xwindow,
- CWBackPixmap,
- &attrs);
-
-#if 0
- 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);
-#endif
-}
-
-static void
-set_background_color (MetaFrame *frame)
-{
- XSetWindowAttributes attrs;
-
- attrs.background_pixel = frame->bg_pixel;
- XChangeWindowAttributes (frame->window->display->xdisplay,
- frame->xwindow,
- CWBackPixel,
- &attrs);
-}
void
meta_window_ensure_frame (MetaWindow *window)
@@ -197,24 +38,18 @@ meta_window_ensure_frame (MetaWindow *window)
frame->window = window;
frame->xwindow = None;
- frame->theme_acquired = FALSE;
- frame->grab = NULL;
- frame->current_control = META_FRAME_CONTROL_NONE;
- frame->tooltip_timeout = 0;
frame->rect = window->rect;
frame->child_x = 0;
frame->child_y = 0;
frame->bottom_height = 0;
frame->right_width = 0;
- frame->bg_pixel = 0;
frame->mapped = FALSE;
-
- frame->edges_exposed = FALSE;
- frame->title_exposed = FALSE;
- attrs.event_mask = EVENT_MASK;
+ attrs.event_mask = SubstructureRedirectMask |
+ StructureNotifyMask | SubstructureNotifyMask |
+ EnterWindowMask | LeaveWindowMask;
frame->xwindow = XCreateWindow (window->display->xdisplay,
window->screen->xroot,
@@ -229,6 +64,9 @@ meta_window_ensure_frame (MetaWindow *window)
CWEventMask,
&attrs);
+ /* So our UI can find the window ID */
+ XFlush (window->display->xdisplay);
+
meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow);
meta_display_register_x_window (window->display, &frame->xwindow, window);
@@ -254,6 +92,8 @@ meta_window_ensure_frame (MetaWindow *window)
window->rect.x,
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;
@@ -270,19 +110,7 @@ meta_window_destroy_frame (MetaWindow *window)
frame = window->frame;
- if (frame->title_exposed || frame->edges_exposed)
- {
- draw_pending = g_slist_remove (draw_pending, frame);
- }
-
- if (frame->tooltip_timeout)
- clear_tip (frame);
-
- if (frame->theme_data)
- {
- meta_frame_init_info (frame, &info);
- window->screen->engine->release_frame (&info, frame->theme_data);
- }
+ meta_ui_remove_frame (window->screen->ui, frame->xwindow);
/* Unparent the client window; it may be destroyed,
* thus the error trap.
@@ -315,6 +143,68 @@ meta_window_destroy_frame (MetaWindow *window)
meta_window_queue_calc_showing (window);
}
+
+MetaFrameFlags
+meta_frame_get_flags (MetaFrame *frame)
+{
+ MetaFrameFlags flags;
+
+ flags =
+ META_FRAME_ALLOWS_MENU | META_FRAME_ALLOWS_RESIZE;
+
+ if (frame->window->has_close_func)
+ flags |= META_FRAME_ALLOWS_DELETE;
+
+ if (frame->window->type == META_WINDOW_NORMAL)
+ flags |= (META_FRAME_ALLOWS_ICONIFY | META_FRAME_ALLOWS_MAXIMIZE);
+
+ if (!frame->window->has_maximize_func)
+ flags &= ~META_FRAME_ALLOWS_MAXIMIZE;
+
+ if (!frame->window->has_minimize_func)
+ flags &= ~META_FRAME_ALLOWS_MINIMIZE;
+
+ if (frame->window->has_focus)
+ flags |= META_FRAME_HAS_FOCUS;
+
+ if (frame->window->shaded)
+ flags |= META_FRAME_SHADED;
+
+ if (frame->window->on_all_workspaces)
+ flags |= META_FRAME_STUCK;
+}
+
+void
+meta_frame_calc_geometry (MetaFrame *frame,
+ MetaFrameGeometry *geomp)
+{
+ MetaFrameGeometry geom;
+ MetaWindow *window;
+
+ window = frame->window;
+
+ meta_ui_get_frame_geometry (window->screen->ui,
+ frame->xwindow,
+ &geom.top_height,
+ &geom.bottom_height,
+ &geom.left_width,
+ &geom.right_width);
+
+ *geomp = geom;
+}
+
+static void
+set_background_none (MetaFrame *frame)
+{
+ XSetWindowAttributes attrs;
+
+ attrs.background_pixmap = None;
+ XChangeWindowAttributes (frame->window->display->xdisplay,
+ frame->xwindow,
+ CWBackPixmap,
+ &attrs);
+}
+
void
meta_frame_sync_to_window (MetaFrame *frame,
gboolean need_move,
@@ -328,7 +218,8 @@ meta_frame_sync_to_window (MetaFrame *frame,
frame->bg_pixel);
/* set bg to none to avoid flicker */
- set_background_none (frame);
+ if (need_resize)
+ set_background_none (frame);
if (need_move && need_resize)
XMoveResizeWindow (frame->window->display->xdisplay,
@@ -346,396 +237,18 @@ meta_frame_sync_to_window (MetaFrame *frame,
XResizeWindow (frame->window->display->xdisplay,
frame->xwindow,
frame->rect.width,
- frame->rect.height);
-
- /* also syncs bg_pixel */
- set_background_color (frame);
- meta_frame_queue_draw (frame);
-}
-
-static void
-meta_frame_draw_now (MetaFrame *frame,
- int x, int y, int width, int height)
-{
- MetaFrameInfo info;
- Pixmap p;
- XGCValues vals;
-
- if (frame->xwindow == None)
- return;
-
- meta_frame_init_info (frame, &info);
-
- if (width < 0)
- width = frame->rect.width;
-
- if (height < 0)
- height = frame->rect.height;
-
- if (width == 0 || height == 0)
- return;
-
- p = XCreatePixmap (frame->window->display->xdisplay,
- frame->xwindow,
- width, height,
- frame->window->screen->visual_info.depth);
-
- vals.foreground = frame->bg_pixel;
- XChangeGC (frame->window->display->xdisplay,
- frame->window->screen->scratch_gc,
- GCForeground,
- &vals);
-
- XFillRectangle (frame->window->display->xdisplay,
- p,
- frame->window->screen->scratch_gc,
- 0, 0,
- width, height);
-
- info.drawable = p;
- info.xoffset = - x;
- info.yoffset = - y;
-
- frame->window->screen->engine->expose_frame (&info,
- 0, 0, width, height,
- frame->theme_data);
-
- XCopyArea (frame->window->display->xdisplay,
- p, frame->xwindow,
- frame->window->screen->scratch_gc,
- 0, 0,
- width, height,
- x, y);
+ frame->rect.height);
- XFreePixmap (frame->window->display->xdisplay,
- p);
-
- frame->title_exposed = FALSE;
- frame->edges_exposed = FALSE;
-}
-
-static gboolean
-draw_idle (gpointer data)
-{
- GSList *tmp;
-
- tmp = draw_pending;
- while (tmp != NULL)
- {
- int yoffset;
- MetaFrame *frame;
-
- frame = tmp->data;
-
- yoffset = 0;
- if (!frame->title_exposed)
- yoffset += frame->child_y;
-
- meta_frame_draw_now (frame, 0, yoffset,
- frame->rect.width,
- frame->rect.height - yoffset);
- tmp = tmp->next;
- }
- g_slist_free (draw_pending);
- draw_pending = NULL;
-
- draw_handler = 0;
- return FALSE;
+ if (need_resize)
+ meta_ui_reset_frame_bg (frame->window->screen->ui,
+ frame->xwindow);
}
void
meta_frame_queue_draw (MetaFrame *frame)
{
- if (draw_handler == 0)
- draw_handler = g_idle_add (draw_idle, NULL);
-
- if (!(frame->title_exposed || frame->edges_exposed))
- draw_pending = g_slist_prepend (draw_pending, frame);
-
- frame->title_exposed = TRUE;
- frame->edges_exposed = TRUE;
-}
-
-static void
-frame_query_root_pointer (MetaFrame *frame,
- int *x, int *y)
-{
- Window root_return, child_return;
- int root_x_return, root_y_return;
- int win_x_return, win_y_return;
- unsigned int mask_return;
-
- XQueryPointer (frame->window->display->xdisplay,
- frame->xwindow,
- &root_return,
- &child_return,
- &root_x_return,
- &root_y_return,
- &win_x_return,
- &win_y_return,
- &mask_return);
-
- if (x)
- *x = root_x_return;
- if (y)
- *y = root_y_return;
-}
-
-static void
-show_tip_now (MetaFrame *frame)
-{
- const char *tiptext;
-
- tiptext = NULL;
- switch (frame->current_control)
- {
- case META_FRAME_CONTROL_TITLE:
- break;
- case META_FRAME_CONTROL_DELETE:
- tiptext = _("Close Window");
- break;
- case META_FRAME_CONTROL_MENU:
- tiptext = _("Menu");
- break;
- case META_FRAME_CONTROL_ICONIFY:
- tiptext = _("Minimize Window");
- break;
- case META_FRAME_CONTROL_MAXIMIZE:
- tiptext = _("Maximize Window");
- break;
- case META_FRAME_CONTROL_RESIZE_SE:
- break;
- case META_FRAME_CONTROL_RESIZE_S:
- break;
- case META_FRAME_CONTROL_RESIZE_SW:
- break;
- case META_FRAME_CONTROL_RESIZE_N:
- break;
- case META_FRAME_CONTROL_RESIZE_NE:
- break;
- case META_FRAME_CONTROL_RESIZE_NW:
- break;
- case META_FRAME_CONTROL_RESIZE_W:
- break;
- case META_FRAME_CONTROL_RESIZE_E:
- break;
- case META_FRAME_CONTROL_NONE:
- break;
- }
-
- if (tiptext)
- {
- int x, y, width, height;
- MetaFrameInfo info;
-
- meta_frame_init_info (frame, &info);
- frame->window->screen->engine->get_control_rect (&info,
- frame->current_control,
- &x, &y, &width, &height,
- frame->theme_data);
-
- /* Display tip a couple pixels below control */
- meta_screen_show_tip (frame->window->screen,
- frame->rect.x + x,
- frame->rect.y + y + height + 2,
- tiptext);
- }
-}
-
-static gboolean
-tip_timeout_func (gpointer data)
-{
- MetaFrame *frame;
-
- frame = data;
-
- show_tip_now (frame);
-
- return FALSE;
-}
-
-#define TIP_DELAY 250
-static void
-queue_tip (MetaFrame *frame)
-{
- if (frame->tooltip_timeout)
- g_source_remove (frame->tooltip_timeout);
-
- frame->tooltip_timeout = g_timeout_add (250,
- tip_timeout_func,
- frame);
-}
-
-static void
-clear_tip (MetaFrame *frame)
-{
- if (frame->tooltip_timeout)
- {
- g_source_remove (frame->tooltip_timeout);
- frame->tooltip_timeout = 0;
- }
- meta_screen_hide_tip (frame->window->screen);
-}
-
-static MetaFrameControl
-frame_get_control (MetaFrame *frame,
- int x, int y)
-{
- MetaFrameInfo info;
-
- if (x < 0 || y < 0 ||
- x > frame->rect.width || y > frame->rect.height)
- return META_FRAME_CONTROL_NONE;
-
- meta_frame_init_info (frame, &info);
-
- return frame->window->screen->engine->get_control (&info,
- x, y,
- frame->theme_data);
-}
-
-static void
-update_move (MetaFrame *frame,
- int x,
- int y)
-{
- int dx, dy;
-
- dx = x - frame->grab->start_root_x;
- dy = y - frame->grab->start_root_y;
-
- frame->window->user_has_moved = TRUE;
- meta_window_move (frame->window,
- frame->grab->start_window_x + dx,
- frame->grab->start_window_y + dy);
-}
-
-static void
-update_resize_se (MetaFrame *frame,
- int x, int y)
-{
- int dx, dy;
-
- dx = x - frame->grab->start_root_x;
- dy = y - frame->grab->start_root_y;
-
- frame->window->user_has_resized = TRUE;
- meta_window_resize (frame->window,
- frame->grab->start_window_x + dx,
- frame->grab->start_window_y + dy);
-}
-
-static void
-update_current_control (MetaFrame *frame,
- int x_root, int y_root)
-{
- MetaFrameControl old;
-
- if (frame->grab)
- return;
-
- old = frame->current_control;
-
- frame->current_control = frame_get_control (frame,
- x_root - frame->rect.x,
- y_root - frame->rect.y);
-
- if (old != frame->current_control)
- {
- meta_frame_queue_draw (frame);
-
- if (frame->current_control == META_FRAME_CONTROL_NONE)
- clear_tip (frame);
- else
- queue_tip (frame);
- }
-}
-
-static void
-grab_action (MetaFrame *frame,
- MetaFrameAction action,
- Time time)
-{
- meta_verbose ("Grabbing action %d\n", action);
-
- frame->grab = g_new0 (MetaFrameActionGrab, 1);
-
- if (XGrabPointer (frame->window->display->xdisplay,
- frame->xwindow,
- False,
- ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | PointerMotionHintMask,
- GrabModeAsync, GrabModeAsync,
- None,
- None,
- time) != GrabSuccess)
- meta_warning ("Grab for frame action failed\n");
-
- frame->grab->action = action;
-
- /* display ACTIVE state */
- meta_frame_queue_draw (frame);
-
- clear_tip (frame);
-}
-
-static void
-ungrab_action (MetaFrame *frame,
- Time time)
-{
- int x, y;
-
- meta_verbose ("Ungrabbing action %d\n", frame->grab->action);
-
- XUngrabPointer (frame->window->display->xdisplay,
- time);
-
- g_free (frame->grab);
- frame->grab = NULL;
-
- frame_query_root_pointer (frame, &x, &y);
- update_current_control (frame, x, y);
-
- /* undisplay ACTIVE state */
- meta_frame_queue_draw (frame);
-
- queue_tip (frame);
-}
-
-static void
-get_menu_items (MetaFrame *frame,
- MetaFrameInfo *info,
- MetaMessageWindowMenuOps *ops,
- MetaMessageWindowMenuOps *insensitive)
-{
- *ops = 0;
- *insensitive = 0;
-
- if (info->flags & META_FRAME_CONTROL_MAXIMIZE)
- {
- if (frame->window->maximized)
- *ops |= META_MESSAGE_MENU_UNMAXIMIZE;
- else
- *ops |= META_MESSAGE_MENU_MAXIMIZE;
- }
-
- if (frame->window->shaded)
- *ops |= META_MESSAGE_MENU_UNSHADE;
- else
- *ops |= META_MESSAGE_MENU_SHADE;
-
- if (frame->window->on_all_workspaces)
- *ops |= META_MESSAGE_MENU_UNSTICK;
- else
- *ops |= META_MESSAGE_MENU_STICK;
-
- *ops |= (META_MESSAGE_MENU_DELETE | META_MESSAGE_MENU_WORKSPACES | META_MESSAGE_MENU_MINIMIZE);
-
- if (!(info->flags & META_FRAME_CONTROL_ICONIFY))
- *insensitive |= META_MESSAGE_MENU_MINIMIZE;
-
- if (!(info->flags & META_FRAME_CONTROL_DELETE))
- *insensitive |= META_MESSAGE_MENU_DELETE;
+ meta_ui_queue_frame_draw (frame->window->screen->ui,
+ frame->xwindow);
}
gboolean
@@ -749,204 +262,10 @@ meta_frame_event (MetaFrame *frame,
case KeyRelease:
break;
case ButtonPress:
- /* you can use button 2 to move a window without raising it */
- if (event->xbutton.button == 1)
- meta_window_raise (frame->window);
-
- update_current_control (frame,
- event->xbutton.x_root,
- event->xbutton.y_root);
-
- if (frame->grab == NULL)
- {
- MetaFrameControl control;
- control = frame->current_control;
-
- if (control == META_FRAME_CONTROL_TITLE &&
- event->xbutton.button == 1 &&
- meta_display_is_double_click (frame->window->display))
- {
- meta_verbose ("Double click on title\n");
-
- /* FIXME this catches double click that starts elsewhere
- * with the second click on title, maybe no one will
- * ever notice
- */
-
- if (frame->window->shaded)
- meta_window_unshade (frame->window);
- else
- meta_window_shade (frame->window);
- }
- else if (((control == META_FRAME_CONTROL_TITLE ||
- control == META_FRAME_CONTROL_NONE) &&
- event->xbutton.button == 1) ||
- event->xbutton.button == 2)
- {
- meta_verbose ("Begin move on %s\n",
- frame->window->desc);
- grab_action (frame, META_FRAME_ACTION_MOVING,
- event->xbutton.time);
- frame->grab->start_root_x = event->xbutton.x_root;
- frame->grab->start_root_y = event->xbutton.y_root;
- /* pos of client in root coords */
- frame->grab->start_window_x =
- frame->rect.x + frame->window->rect.x;
- frame->grab->start_window_y =
- frame->rect.y + frame->window->rect.y;
- frame->grab->start_button = event->xbutton.button;
- }
- else if (control == META_FRAME_CONTROL_DELETE &&
- event->xbutton.button == 1)
- {
- meta_verbose ("Close control clicked on %s\n",
- frame->window->desc);
- grab_action (frame, META_FRAME_ACTION_DELETING,
- event->xbutton.time);
- frame->grab->start_button = event->xbutton.button;
- }
- else if (control == META_FRAME_CONTROL_MAXIMIZE &&
- event->xbutton.button == 1)
- {
- meta_verbose ("Maximize control clicked on %s\n",
- frame->window->desc);
- grab_action (frame, META_FRAME_ACTION_TOGGLING_MAXIMIZE,
- event->xbutton.time);
- frame->grab->start_button = event->xbutton.button;
- }
- else if (control == META_FRAME_CONTROL_RESIZE_SE &&
- event->xbutton.button == 1)
- {
- meta_verbose ("Resize control clicked on %s\n",
- frame->window->desc);
- grab_action (frame, META_FRAME_ACTION_RESIZING_SE,
- event->xbutton.time);
- frame->grab->start_root_x = event->xbutton.x_root;
- frame->grab->start_root_y = event->xbutton.y_root;
- frame->grab->start_window_x = frame->window->rect.width;
- frame->grab->start_window_y = frame->window->rect.height;
- frame->grab->start_button = event->xbutton.button;
- }
- else if (control == META_FRAME_CONTROL_MENU &&
- event->xbutton.button == 1)
- {
- int x, y, width, height;
- MetaFrameInfo info;
- MetaMessageWindowMenuOps ops;
- MetaMessageWindowMenuOps insensitive;
-
- meta_verbose ("Menu control clicked on %s\n",
- frame->window->desc);
-
- meta_frame_init_info (frame, &info);
- frame->window->screen->engine->get_control_rect (&info,
- META_FRAME_CONTROL_MENU,
- &x, &y, &width, &height,
- frame->theme_data);
-
- /* Let the menu get a grab. The user could release button
- * before the menu gets the grab, in which case the
- * menu gets somewhat confused, but it's not that
- * disastrous.
- */
- XUngrabPointer (frame->window->display->xdisplay,
- event->xbutton.time);
-
- get_menu_items (frame, &info, &ops, &insensitive);
-
- meta_ui_slave_show_window_menu (frame->window->screen->uislave,
- frame->window,
- frame->rect.x + x,
- frame->rect.y + y + height,
- event->xbutton.button,
- ops, insensitive,
- event->xbutton.time);
- }
- }
break;
case ButtonRelease:
- if (frame->grab)
- meta_debug_spew ("Here! grab %p action %d buttons %d %d\n",
- frame->grab, frame->grab->action, frame->grab->start_button, event->xbutton.button);
- if (frame->grab &&
- event->xbutton.button == frame->grab->start_button)
- {
- switch (frame->grab->action)
- {
- case META_FRAME_ACTION_MOVING:
- update_move (frame, event->xbutton.x_root, event->xbutton.y_root);
- ungrab_action (frame, event->xbutton.time);
- update_current_control (frame,
- event->xbutton.x_root, event->xbutton.y_root);
- break;
-
- case META_FRAME_ACTION_RESIZING_SE:
- update_resize_se (frame, event->xbutton.x_root, event->xbutton.y_root);
- ungrab_action (frame, event->xbutton.time);
- update_current_control (frame,
- event->xbutton.x_root, event->xbutton.y_root);
- break;
-
- case META_FRAME_ACTION_DELETING:
- /* Must ungrab before getting "real" control position */
- ungrab_action (frame, event->xbutton.time);
- update_current_control (frame,
- event->xbutton.x_root,
- event->xbutton.y_root);
- /* delete if we're still over the button */
- if (frame->current_control == META_FRAME_CONTROL_DELETE)
- meta_window_delete (frame->window, event->xbutton.time);
- break;
- case META_FRAME_ACTION_TOGGLING_MAXIMIZE:
- /* Must ungrab before getting "real" control position */
- ungrab_action (frame, event->xbutton.time);
- update_current_control (frame,
- event->xbutton.x_root,
- event->xbutton.y_root);
- /* delete if we're still over the button */
- if (frame->current_control == META_FRAME_CONTROL_MAXIMIZE)
- {
- if (frame->window->maximized)
- meta_window_unmaximize (frame->window);
- else
- meta_window_maximize (frame->window);
- }
- break;
- default:
- meta_warning ("Unhandled action in button release\n");
- break;
- }
- }
break;
case MotionNotify:
- {
- int x, y;
-
- frame_query_root_pointer (frame, &x, &y);
- if (frame->grab)
- {
- switch (frame->grab->action)
- {
- case META_FRAME_ACTION_MOVING:
- update_move (frame, x, y);
- break;
-
- case META_FRAME_ACTION_RESIZING_SE:
- update_resize_se (frame, x, y);
- break;
-
- case META_FRAME_ACTION_NONE:
-
- break;
- default:
- break;
- }
- }
- else
- {
- update_current_control (frame, x, y);
- }
- }
break;
case EnterNotify:
/* We handle it here if a decorated window
@@ -957,7 +276,6 @@ meta_frame_event (MetaFrame *frame,
event->xcrossing.time);
break;
case LeaveNotify:
- update_current_control (frame, -1, -1);
break;
case FocusIn:
break;
@@ -966,13 +284,6 @@ meta_frame_event (MetaFrame *frame,
case KeymapNotify:
break;
case Expose:
- {
- gboolean title_was_exposed = frame->title_exposed;
- meta_frame_queue_draw (frame);
- if (!title_was_exposed &&
- event->xexpose.y > frame->child_y)
- frame->title_exposed = FALSE;
- }
break;
case GraphicsExpose:
break;
@@ -995,12 +306,8 @@ meta_frame_event (MetaFrame *frame,
}
break;
case UnmapNotify:
- if (frame->grab)
- ungrab_action (frame, CurrentTime);
break;
case MapNotify:
- if (frame->grab)
- ungrab_action (frame, CurrentTime);
break;
case MapRequest:
break;
@@ -1009,13 +316,6 @@ meta_frame_event (MetaFrame *frame,
case ConfigureNotify:
break;
case ConfigureRequest:
- {
- /* This is a request from the UISlave, or else a client
- * that's completely out of line. We call
- * meta_window_move_resize() using this information.
- */
-
- }
break;
case GravityNotify:
break;
diff --git a/src/frame.h b/src/frame.h
index 314d1c200..642491bb5 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -24,16 +24,14 @@
#include "window.h"
-typedef enum
-{
- META_FRAME_ACTION_NONE,
- META_FRAME_ACTION_MOVING,
- META_FRAME_ACTION_DELETING,
- META_FRAME_ACTION_TOGGLING_MAXIMIZE,
- META_FRAME_ACTION_RESIZING_SE
-} MetaFrameAction;
-
-typedef struct _MetaFrameActionGrab MetaFrameActionGrab;
+struct _MetaFrameGeometry
+{
+ /* border sizes (space between frame and child) */
+ int left_width;
+ int right_width;
+ int top_height;
+ int bottom_height;
+};
struct _MetaFrame
{
@@ -47,26 +45,14 @@ struct _MetaFrame
* frame, not the result of ConfigureNotify
*/
MetaRectangle rect;
+
+ /* position of client, size of frame */
int child_x;
int child_y;
int right_width;
int bottom_height;
-
- gpointer theme_data;
- gulong bg_pixel;
-
- MetaFrameActionGrab *grab;
-
- MetaFrameControl current_control;
- guint tooltip_timeout;
-
- guint theme_acquired : 1;
guint mapped : 1;
-
- /* world's lamest expose compression */
- guint edges_exposed : 1;
- guint title_exposed : 1;
};
void meta_window_ensure_frame (MetaWindow *window);
@@ -75,10 +61,10 @@ 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 */
+MetaFrameFlags meta_frame_get_flags (MetaFrame *frame);
+
+/* These 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);
void meta_frame_sync_to_window (MetaFrame *frame,
gboolean need_move,
diff --git a/src/frames.c b/src/frames.c
index 7fb0130ad..dac569836 100644
--- a/src/frames.c
+++ b/src/frames.c
@@ -21,15 +21,35 @@
#include "frames.h"
+
+struct _MetaFrameActionGrab
+{
+ MetaFrameAction action;
+ /* 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;
+};
+
+
+/* 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)
+
struct _MetaFrame
{
Window xwindow;
GdkWindow *window;
PangoLayout *layout;
MetaFrameFlags flags;
- /* w/h of frame window */
- int width;
- int height;
};
struct _MetaFrameProperties
@@ -130,6 +150,7 @@ gboolean meta_frames_window_state_event (GtkWidget *widget,
static void meta_frames_calc_geometry (MetaFrames *frames,
+ MetaFrame *frame,
MetaFrameGeometry *fgeom);
static MetaFrame* meta_frames_lookup_window (MetaFrames *frames,
@@ -252,13 +273,6 @@ meta_frames_init (MetaFrames *frames)
}
static void
-meta_frames_destroy (GtkObject *object)
-{
-
- GTK_OBJECT_CLASS (parent_class)->destroy (object);
-}
-
-static void
listify_func (gpointer key, gpointer value, gpointer data)
{
GSList **listp;
@@ -268,14 +282,14 @@ listify_func (gpointer key, gpointer value, gpointer data)
}
static void
-meta_frames_finalize (GObject *object)
+meta_frames_destroy (GtkObject *object)
{
- MetaFrames *frames;
GSList *winlist;
GSList *tmp;
+ MetaFrames *frames;
frames = META_FRAMES (object);
-
+
winlist = NULL;
g_hash_table_foreach (frames->frames,
listify_func,
@@ -295,6 +309,16 @@ meta_frames_finalize (GObject *object)
}
g_slist_free (winlist);
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
+}
+
+static void
+meta_frames_finalize (GObject *object)
+{
+ MetaFrames *frames;
+
+ frames = META_FRAMES (object);
+
g_assert (g_hash_table_size (frames->frames) == 0);
g_hash_table_destroy (frames->frames);
@@ -410,9 +434,13 @@ meta_frames_calc_geometry (MetaFrames *frames,
gboolean shaded;
MetaFrameProperties props;
int buttons_height, title_height, spacer_height;
+ int width, height;
props = *(frames->props);
+ meta_core_get_frame_size (gdk_display, frame->xwindow,
+ &width, &height);
+
buttons_height = props.button_height +
props.button_border.top + props.button_border.bottom;
title_height = frames->text_height +
@@ -431,7 +459,7 @@ meta_frames_calc_geometry (MetaFrames *frames,
else
fgeom->bottom_height = props.bottom_height;
- x = frame->width - fgeom->button_inset;
+ x = width - fgeom->button_inset;
/* center buttons */
button_y = (fgeom->top_height -
@@ -570,17 +598,13 @@ meta_frames_manage_window (MetaFrames *frames,
g_return_if_fail (GDK_IS_WINDOW (window));
frame = g_new (MetaFrame, 1);
-
- gdk_error_trap_push ();
frame->window = gdk_window_foreign_new (xwindow);
if (frame->window == NULL)
{
- gdk_flush ();
- gdk_error_trap_pop ();
g_free (frame);
- meta_ui_warning ("Frame 0x%lx disappeared as we managed it\n", xwindow);
+ meta_bug ("Frame 0x%lx doesn't exist\n", xwindow);
return;
}
@@ -594,9 +618,6 @@ meta_frames_manage_window (MetaFrames *frames,
GDK_BUTTON_RELEASE_MASK |
GDK_STRUCTURE_MASK);
- gdk_drawable_get_size (GDK_DRAWABLE (frame->window),
- &frame->width, &frame->height);
-
/* This shouldn't be required if we don't select for button
* press in frame.c?
*/
@@ -607,15 +628,8 @@ meta_frames_manage_window (MetaFrames *frames,
GrabModeAsync, GrabModeAsync,
False, None);
- gdk_flush ();
- if (gdk_error_trap_pop ())
- {
- g_object_unref (G_OBJECT (frame->window));
- g_free (frame);
- meta_ui_warning ("Errors managing frame 0x%lx\n", xwindow);
- return;
- }
-
+ XFlush (gdk_display);
+
frame->xwindow = xwindow;
frame->layout = NULL;
frame->flags = 0;
@@ -657,6 +671,102 @@ meta_frames_lookup_window (MetaFrames *frames,
return frame;
}
+void
+meta_frames_get_geometry (MetaFrames *frames,
+ Window xwindow,
+ int *top_height, int *bottom_height,
+ int *left_width, int *right_width)
+{
+ MetaFrameGeometry fgeom;
+
+ MetaFrame *frame;
+
+ frame = meta_frames_lookup_window (frames, xwindow);
+
+ if (frame == NULL)
+ meta_bug ("No such frame 0x%lx\n", xwindow);
+
+ meta_frames_calc_geometry (frames, frame, &fgeom);
+
+ if (top_height)
+ *top_height = fgeom.top_height;
+ if (bottom_height)
+ *bottom_height = fgeom.bottom_height;
+ if (left_width)
+ *left_width = fgeom.left_width;
+ if (right_width)
+ *right_width = fgeom.right_width;
+}
+
+void
+meta_frames_reset_bg (MetaFrames *frames,
+ Window xwindow)
+{
+ GtkWidget *widget;
+ MetaFrame *frame;
+
+ widget = GTK_WIDGET (frames);
+
+ frame = meta_frames_lookup_window (frames, xwindow);
+
+ gtk_style_set_background (widget->style, frame->window, GTK_STATE_NORMAL);
+}
+
+void
+meta_frames_set_flags (MetaFrames *frames,
+ Window xwindow,
+ MetaFrameFlags flags)
+{
+ GtkWidget *widget;
+ MetaFrame *frame;
+
+ widget = GTK_WIDGET (frames);
+
+ frame = meta_frames_lookup_window (frames, xwindow);
+
+ if (frame->flags == flags)
+ return;
+
+ frame->flags = flags;
+
+ gdk_window_invalidate_rect (frame->window, NULL, FALSE);
+}
+
+void
+meta_frames_queue_draw (MetaFrames *frames,
+ Window xwindow)
+{
+ GtkWidget *widget;
+ MetaFrame *frame;
+
+ widget = GTK_WIDGET (frames);
+
+ frame = meta_frames_lookup_window (frames, xwindow);
+
+ gdk_window_invalidate_rect (frame->window, NULL, FALSE);
+}
+
+void
+meta_frames_set_title (MetaFrames *frames,
+ Window xwindow,
+ const char *title)
+{
+ GtkWidget *widget;
+ MetaFrame *frame;
+
+ widget = GTK_WIDGET (frames);
+
+ frame = meta_frames_lookup_window (frames, xwindow);
+
+ if (frame->layout == NULL)
+ frame->layout = gtk_widget_create_pango_layout (widget,
+ title);
+ else
+ pango_layout_set_text (frame->layout, title, -1);
+
+ gdk_window_invalidate_rect (frame->window, NULL, FALSE);
+}
+
gboolean
meta_frames_button_press_event (GtkWidget *widget,
GdkEventButton *event)
@@ -929,3 +1039,596 @@ meta_frames_window_state_event (GtkWidget *widget,
return TRUE;
}
+
+#if 0
+
+static void
+frame_query_root_pointer (MetaFrame *frame,
+ int *x, int *y)
+{
+ Window root_return, child_return;
+ int root_x_return, root_y_return;
+ int win_x_return, win_y_return;
+ unsigned int mask_return;
+
+ XQueryPointer (frame->window->display->xdisplay,
+ frame->xwindow,
+ &root_return,
+ &child_return,
+ &root_x_return,
+ &root_y_return,
+ &win_x_return,
+ &win_y_return,
+ &mask_return);
+
+ if (x)
+ *x = root_x_return;
+ if (y)
+ *y = root_y_return;
+}
+
+static void
+show_tip_now (MetaFrame *frame)
+{
+ const char *tiptext;
+
+ tiptext = NULL;
+ switch (frame->current_control)
+ {
+ case META_FRAME_CONTROL_TITLE:
+ break;
+ case META_FRAME_CONTROL_DELETE:
+ tiptext = _("Close Window");
+ break;
+ case META_FRAME_CONTROL_MENU:
+ tiptext = _("Menu");
+ break;
+ case META_FRAME_CONTROL_ICONIFY:
+ tiptext = _("Minimize Window");
+ break;
+ case META_FRAME_CONTROL_MAXIMIZE:
+ tiptext = _("Maximize Window");
+ break;
+ case META_FRAME_CONTROL_RESIZE_SE:
+ break;
+ case META_FRAME_CONTROL_RESIZE_S:
+ break;
+ case META_FRAME_CONTROL_RESIZE_SW:
+ break;
+ case META_FRAME_CONTROL_RESIZE_N:
+ break;
+ case META_FRAME_CONTROL_RESIZE_NE:
+ break;
+ case META_FRAME_CONTROL_RESIZE_NW:
+ break;
+ case META_FRAME_CONTROL_RESIZE_W:
+ break;
+ case META_FRAME_CONTROL_RESIZE_E:
+ break;
+ case META_FRAME_CONTROL_NONE:
+ break;
+ }
+
+ if (tiptext)
+ {
+ int x, y, width, height;
+ MetaFrameInfo info;
+
+ meta_frame_init_info (frame, &info);
+ frame->window->screen->engine->get_control_rect (&info,
+ frame->current_control,
+ &x, &y, &width, &height,
+ frame->theme_data);
+
+ /* Display tip a couple pixels below control */
+ meta_screen_show_tip (frame->window->screen,
+ frame->rect.x + x,
+ frame->rect.y + y + height + 2,
+ tiptext);
+ }
+}
+
+static gboolean
+tip_timeout_func (gpointer data)
+{
+ MetaFrame *frame;
+
+ frame = data;
+
+ show_tip_now (frame);
+
+ return FALSE;
+}
+
+#define TIP_DELAY 250
+static void
+queue_tip (MetaFrame *frame)
+{
+ if (frame->tooltip_timeout)
+ g_source_remove (frame->tooltip_timeout);
+
+ frame->tooltip_timeout = g_timeout_add (250,
+ tip_timeout_func,
+ frame);
+}
+
+static void
+clear_tip (MetaFrame *frame)
+{
+ if (frame->tooltip_timeout)
+ {
+ g_source_remove (frame->tooltip_timeout);
+ frame->tooltip_timeout = 0;
+ }
+ meta_screen_hide_tip (frame->window->screen);
+}
+
+static MetaFrameControl
+frame_get_control (MetaFrame *frame,
+ int x, int y)
+{
+ MetaFrameInfo info;
+
+ if (x < 0 || y < 0 ||
+ x > frame->rect.width || y > frame->rect.height)
+ return META_FRAME_CONTROL_NONE;
+
+ meta_frame_init_info (frame, &info);
+
+ return frame->window->screen->engine->get_control (&info,
+ x, y,
+ frame->theme_data);
+}
+
+static void
+update_move (MetaFrame *frame,
+ int x,
+ int y)
+{
+ int dx, dy;
+
+ dx = x - frame->grab->start_root_x;
+ dy = y - frame->grab->start_root_y;
+
+ frame->window->user_has_moved = TRUE;
+ meta_window_move (frame->window,
+ frame->grab->start_window_x + dx,
+ frame->grab->start_window_y + dy);
+}
+
+static void
+update_resize_se (MetaFrame *frame,
+ int x, int y)
+{
+ int dx, dy;
+
+ dx = x - frame->grab->start_root_x;
+ dy = y - frame->grab->start_root_y;
+
+ frame->window->user_has_resized = TRUE;
+ meta_window_resize (frame->window,
+ frame->grab->start_window_x + dx,
+ frame->grab->start_window_y + dy);
+}
+
+static void
+update_current_control (MetaFrame *frame,
+ int x_root, int y_root)
+{
+ MetaFrameControl old;
+
+ if (frame->grab)
+ return;
+
+ old = frame->current_control;
+
+ frame->current_control = frame_get_control (frame,
+ x_root - frame->rect.x,
+ y_root - frame->rect.y);
+
+ if (old != frame->current_control)
+ {
+ meta_frame_queue_draw (frame);
+
+ if (frame->current_control == META_FRAME_CONTROL_NONE)
+ clear_tip (frame);
+ else
+ queue_tip (frame);
+ }
+}
+
+static void
+grab_action (MetaFrame *frame,
+ MetaFrameAction action,
+ Time time)
+{
+ meta_verbose ("Grabbing action %d\n", action);
+
+ frame->grab = g_new0 (MetaFrameActionGrab, 1);
+
+ if (XGrabPointer (frame->window->display->xdisplay,
+ frame->xwindow,
+ False,
+ ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | PointerMotionHintMask,
+ GrabModeAsync, GrabModeAsync,
+ None,
+ None,
+ time) != GrabSuccess)
+ meta_warning ("Grab for frame action failed\n");
+
+ frame->grab->action = action;
+
+ /* display ACTIVE state */
+ meta_frame_queue_draw (frame);
+
+ clear_tip (frame);
+}
+
+static void
+ungrab_action (MetaFrame *frame,
+ Time time)
+{
+ int x, y;
+
+ meta_verbose ("Ungrabbing action %d\n", frame->grab->action);
+
+ XUngrabPointer (frame->window->display->xdisplay,
+ time);
+
+ g_free (frame->grab);
+ frame->grab = NULL;
+
+ frame_query_root_pointer (frame, &x, &y);
+ update_current_control (frame, x, y);
+
+ /* undisplay ACTIVE state */
+ meta_frame_queue_draw (frame);
+
+ queue_tip (frame);
+}
+
+static void
+get_menu_items (MetaFrame *frame,
+ MetaFrameInfo *info,
+ MetaMessageWindowMenuOps *ops,
+ MetaMessageWindowMenuOps *insensitive)
+{
+ *ops = 0;
+ *insensitive = 0;
+
+ if (info->flags & META_FRAME_CONTROL_MAXIMIZE)
+ {
+ if (frame->window->maximized)
+ *ops |= META_MESSAGE_MENU_UNMAXIMIZE;
+ else
+ *ops |= META_MESSAGE_MENU_MAXIMIZE;
+ }
+
+ if (frame->window->shaded)
+ *ops |= META_MESSAGE_MENU_UNSHADE;
+ else
+ *ops |= META_MESSAGE_MENU_SHADE;
+
+ if (frame->window->on_all_workspaces)
+ *ops |= META_MESSAGE_MENU_UNSTICK;
+ else
+ *ops |= META_MESSAGE_MENU_STICK;
+
+ *ops |= (META_MESSAGE_MENU_DELETE | META_MESSAGE_MENU_WORKSPACES | META_MESSAGE_MENU_MINIMIZE);
+
+ if (!(info->flags & META_FRAME_CONTROL_ICONIFY))
+ *insensitive |= META_MESSAGE_MENU_MINIMIZE;
+
+ if (!(info->flags & META_FRAME_CONTROL_DELETE))
+ *insensitive |= META_MESSAGE_MENU_DELETE;
+}
+
+gboolean
+meta_frame_event (MetaFrame *frame,
+ XEvent *event)
+{
+ switch (event->type)
+ {
+ case KeyPress:
+ break;
+ case KeyRelease:
+ break;
+ case ButtonPress:
+ /* you can use button 2 to move a window without raising it */
+ if (event->xbutton.button == 1)
+ meta_window_raise (frame->window);
+
+ update_current_control (frame,
+ event->xbutton.x_root,
+ event->xbutton.y_root);
+
+ if (frame->grab == NULL)
+ {
+ MetaFrameControl control;
+ control = frame->current_control;
+
+ if (control == META_FRAME_CONTROL_TITLE &&
+ event->xbutton.button == 1 &&
+ meta_display_is_double_click (frame->window->display))
+ {
+ meta_verbose ("Double click on title\n");
+
+ /* FIXME this catches double click that starts elsewhere
+ * with the second click on title, maybe no one will
+ * ever notice
+ */
+
+ if (frame->window->shaded)
+ meta_window_unshade (frame->window);
+ else
+ meta_window_shade (frame->window);
+ }
+ else if (((control == META_FRAME_CONTROL_TITLE ||
+ control == META_FRAME_CONTROL_NONE) &&
+ event->xbutton.button == 1) ||
+ event->xbutton.button == 2)
+ {
+ meta_verbose ("Begin move on %s\n",
+ frame->window->desc);
+ grab_action (frame, META_FRAME_ACTION_MOVING,
+ event->xbutton.time);
+ frame->grab->start_root_x = event->xbutton.x_root;
+ frame->grab->start_root_y = event->xbutton.y_root;
+ /* pos of client in root coords */
+ frame->grab->start_window_x =
+ frame->rect.x + frame->window->rect.x;
+ frame->grab->start_window_y =
+ frame->rect.y + frame->window->rect.y;
+ frame->grab->start_button = event->xbutton.button;
+ }
+ else if (control == META_FRAME_CONTROL_DELETE &&
+ event->xbutton.button == 1)
+ {
+ meta_verbose ("Close control clicked on %s\n",
+ frame->window->desc);
+ grab_action (frame, META_FRAME_ACTION_DELETING,
+ event->xbutton.time);
+ frame->grab->start_button = event->xbutton.button;
+ }
+ else if (control == META_FRAME_CONTROL_MAXIMIZE &&
+ event->xbutton.button == 1)
+ {
+ meta_verbose ("Maximize control clicked on %s\n",
+ frame->window->desc);
+ grab_action (frame, META_FRAME_ACTION_TOGGLING_MAXIMIZE,
+ event->xbutton.time);
+ frame->grab->start_button = event->xbutton.button;
+ }
+ else if (control == META_FRAME_CONTROL_RESIZE_SE &&
+ event->xbutton.button == 1)
+ {
+ meta_verbose ("Resize control clicked on %s\n",
+ frame->window->desc);
+ grab_action (frame, META_FRAME_ACTION_RESIZING_SE,
+ event->xbutton.time);
+ frame->grab->start_root_x = event->xbutton.x_root;
+ frame->grab->start_root_y = event->xbutton.y_root;
+ frame->grab->start_window_x = frame->window->rect.width;
+ frame->grab->start_window_y = frame->window->rect.height;
+ frame->grab->start_button = event->xbutton.button;
+ }
+ else if (control == META_FRAME_CONTROL_MENU &&
+ event->xbutton.button == 1)
+ {
+ int x, y, width, height;
+ MetaFrameInfo info;
+ MetaMessageWindowMenuOps ops;
+ MetaMessageWindowMenuOps insensitive;
+
+ meta_verbose ("Menu control clicked on %s\n",
+ frame->window->desc);
+
+ meta_frame_init_info (frame, &info);
+ frame->window->screen->engine->get_control_rect (&info,
+ META_FRAME_CONTROL_MENU,
+ &x, &y, &width, &height,
+ frame->theme_data);
+
+ /* Let the menu get a grab. The user could release button
+ * before the menu gets the grab, in which case the
+ * menu gets somewhat confused, but it's not that
+ * disastrous.
+ */
+ XUngrabPointer (frame->window->display->xdisplay,
+ event->xbutton.time);
+
+ get_menu_items (frame, &info, &ops, &insensitive);
+
+ meta_ui_slave_show_window_menu (frame->window->screen->uislave,
+ frame->window,
+ frame->rect.x + x,
+ frame->rect.y + y + height,
+ event->xbutton.button,
+ ops, insensitive,
+ event->xbutton.time);
+ }
+ }
+ break;
+ case ButtonRelease:
+ if (frame->grab)
+ meta_debug_spew ("Here! grab %p action %d buttons %d %d\n",
+ frame->grab, frame->grab->action, frame->grab->start_button, event->xbutton.button);
+ if (frame->grab &&
+ event->xbutton.button == frame->grab->start_button)
+ {
+ switch (frame->grab->action)
+ {
+ case META_FRAME_ACTION_MOVING:
+ update_move (frame, event->xbutton.x_root, event->xbutton.y_root);
+ ungrab_action (frame, event->xbutton.time);
+ update_current_control (frame,
+ event->xbutton.x_root, event->xbutton.y_root);
+ break;
+
+ case META_FRAME_ACTION_RESIZING_SE:
+ update_resize_se (frame, event->xbutton.x_root, event->xbutton.y_root);
+ ungrab_action (frame, event->xbutton.time);
+ update_current_control (frame,
+ event->xbutton.x_root, event->xbutton.y_root);
+ break;
+
+ case META_FRAME_ACTION_DELETING:
+ /* Must ungrab before getting "real" control position */
+ ungrab_action (frame, event->xbutton.time);
+ update_current_control (frame,
+ event->xbutton.x_root,
+ event->xbutton.y_root);
+ /* delete if we're still over the button */
+ if (frame->current_control == META_FRAME_CONTROL_DELETE)
+ meta_window_delete (frame->window, event->xbutton.time);
+ break;
+ case META_FRAME_ACTION_TOGGLING_MAXIMIZE:
+ /* Must ungrab before getting "real" control position */
+ ungrab_action (frame, event->xbutton.time);
+ update_current_control (frame,
+ event->xbutton.x_root,
+ event->xbutton.y_root);
+ /* delete if we're still over the button */
+ if (frame->current_control == META_FRAME_CONTROL_MAXIMIZE)
+ {
+ if (frame->window->maximized)
+ meta_window_unmaximize (frame->window);
+ else
+ meta_window_maximize (frame->window);
+ }
+ break;
+ default:
+ meta_warning ("Unhandled action in button release\n");
+ break;
+ }
+ }
+ break;
+ case MotionNotify:
+ {
+ int x, y;
+
+ frame_query_root_pointer (frame, &x, &y);
+ if (frame->grab)
+ {
+ switch (frame->grab->action)
+ {
+ case META_FRAME_ACTION_MOVING:
+ update_move (frame, x, y);
+ break;
+
+ case META_FRAME_ACTION_RESIZING_SE:
+ update_resize_se (frame, x, y);
+ break;
+
+ case META_FRAME_ACTION_NONE:
+
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ update_current_control (frame, x, y);
+ }
+ }
+ 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:
+ update_current_control (frame, -1, -1);
+ break;
+ case FocusIn:
+ break;
+ case FocusOut:
+ break;
+ case KeymapNotify:
+ break;
+ case Expose:
+ {
+ gboolean title_was_exposed = frame->title_exposed;
+ meta_frame_queue_draw (frame);
+ if (!title_was_exposed &&
+ event->xexpose.y > frame->child_y)
+ frame->title_exposed = FALSE;
+ }
+ break;
+ case GraphicsExpose:
+ break;
+ case NoExpose:
+ break;
+ case VisibilityNotify:
+ break;
+ case CreateNotify:
+ break;
+ case DestroyNotify:
+ {
+ MetaDisplay *display;
+
+ meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently fail or be considered a bug\n", frame->xwindow);
+ display = frame->window->display;
+ meta_error_trap_push (display);
+ meta_window_destroy_frame (frame->window);
+ meta_error_trap_pop (display);
+ return TRUE;
+ }
+ break;
+ case UnmapNotify:
+ if (frame->grab)
+ ungrab_action (frame, CurrentTime);
+ break;
+ case MapNotify:
+ if (frame->grab)
+ ungrab_action (frame, CurrentTime);
+ break;
+ case MapRequest:
+ break;
+ case ReparentNotify:
+ break;
+ case ConfigureNotify:
+ break;
+ case ConfigureRequest:
+ {
+ /* This is a request from the UISlave, or else a client
+ * that's completely out of line. We call
+ * meta_window_move_resize() using this information.
+ */
+
+ }
+ 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;
+ }
+
+ return FALSE;
+}
+#endif
diff --git a/src/frames.h b/src/frames.h
index 444b8b1f5..eb42dd655 100644
--- a/src/frames.h
+++ b/src/frames.h
@@ -24,7 +24,25 @@
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
-#include "messages.h"
+#include "common.h"
+
+typedef enum
+{
+ META_FRAME_CONTROL_NONE,
+ META_FRAME_CONTROL_TITLE,
+ META_FRAME_CONTROL_DELETE,
+ META_FRAME_CONTROL_MENU,
+ META_FRAME_CONTROL_MINIMIZE,
+ META_FRAME_CONTROL_MAXIMIZE,
+ META_FRAME_CONTROL_RESIZE_SE,
+ META_FRAME_CONTROL_RESIZE_S,
+ META_FRAME_CONTROL_RESIZE_SW,
+ META_FRAME_CONTROL_RESIZE_N,
+ META_FRAME_CONTROL_RESIZE_NE,
+ META_FRAME_CONTROL_RESIZE_NW,
+ META_FRAME_CONTROL_RESIZE_W,
+ META_FRAME_CONTROL_RESIZE_E
+} MetaFrameControl;
/* This is one widget that manages all the window frames
* as subwindows.
@@ -73,4 +91,19 @@ void meta_frames_set_title (MetaFrames *frames,
Window xwindow,
const char *title);
+void meta_frames_get_geometry (MetaFrames *frames,
+ Window xwindow,
+ int *top_height, int *bottom_height,
+ int *left_width, int *right_width);
+
+void meta_frames_reset_bg (MetaFrames *frames,
+ Window xwindow);
+
+void meta_frames_set_flags (MetaFrames *frames,
+ Window xwindow,
+ MetaFrameFlags flags);
+
+void meta_frames_queue_draw (MetaFrames *frames,
+ Window xwindow);
+
#endif
diff --git a/src/screen.c b/src/screen.c
index f6029c50a..55715c469 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -23,8 +23,6 @@
#include "util.h"
#include "errors.h"
#include "window.h"
-#include "colors.h"
-#include "uislave.h"
#include "frame.h"
#include "workspace.h"
#include "keybindings.h"
@@ -35,9 +33,6 @@
#include <locale.h>
#include <string.h>
-static void ui_slave_func (MetaUISlave *uislave,
- MetaMessage *message,
- gpointer data);
static char* get_screen_name (MetaDisplay *display,
int number);
@@ -188,10 +183,9 @@ meta_screen_new (MetaDisplay *display,
screen->xroot,
0,
&vals);
-
- screen->uislave = meta_ui_slave_new (screen->screen_name,
- ui_slave_func,
- screen);
+
+ screen->ui = meta_ui_new (screen->display,
+ screen->xscreen);
screen->stack = meta_stack_new (screen);
@@ -397,37 +391,6 @@ meta_screen_for_x_screen (Screen *xscreen)
return meta_display_screen_for_x_screen (display, xscreen);
}
-static void
-ui_slave_func (MetaUISlave *uislave,
- MetaMessage *message,
- gpointer data)
-{
- switch (message->header.message_code)
- {
- case MetaMessageCheckCode:
- meta_verbose ("Received UI slave check message version: %s host alias: %s messages version: %d\n",
- message->check.metacity_version,
- message->check.host_alias,
- message->check.messages_version);
-
- if (strcmp (message->check.metacity_version, VERSION) != 0 ||
- strcmp (message->check.host_alias, HOST_ALIAS) != 0 ||
- message->check.messages_version != META_MESSAGES_VERSION)
- {
- meta_warning ("metacity-uislave has the wrong version; must use the one compiled with metacity\n");
- meta_ui_slave_disable (uislave);
- }
-
- break;
-
- default:
- meta_verbose ("Received unhandled message from UI slave: %d\n",
- message->header.message_code);
- break;
- }
-}
-
-
static char*
get_screen_name (MetaDisplay *display,
int number)
diff --git a/src/screen.h b/src/screen.h
index 24337492a..adcce4729 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -25,6 +25,7 @@
#include "display.h"
#include "theme.h"
#include <X11/Xutil.h>
+#include "ui.h"
typedef void (* MetaScreenWindowFunc) (MetaScreen *screen, MetaWindow *window,
gpointer user_data);
@@ -37,7 +38,7 @@ struct _MetaScreen
Screen *xscreen;
Window xroot;
MetaThemeEngine *engine;
- MetaUISlave *uislave;
+ MetaUI *ui;
MetaWorkspace *active_workspace;
diff --git a/src/ui.c b/src/ui.c
index 41ec45c4a..7479c79c3 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -20,9 +20,93 @@
*/
#include "ui.h"
+#include "frames.h"
+
+struct _MetaUI
+{
+ Display *xdisplay;
+ Screen *xscreen;
+ MetaFrames *frames;
+};
void
meta_ui_init (int *argc, char ***argv)
{
gtk_init (argc, argv);
}
+
+MetaUI*
+meta_ui_new (Display *xdisplay,
+ Screen *screen)
+{
+ MetaUI *ui;
+
+ ui = g_new (MetaUI, 1);
+ ui->xdisplay = xdisplay;
+ ui->xscreen = screen;
+
+ /* FIXME when gtk has multihead use it here */
+ ui->frames = meta_frames_new ();
+ gtk_widget_realize (GTK_WIDGET (ui->frames));
+
+ return ui;
+}
+
+void
+meta_ui_free (MetaUI *ui)
+{
+ gtk_widget_destroy (GTK_WIDGET (ui->frames));
+
+ g_free (ui);
+}
+
+void
+meta_ui_get_frame_geometry (MetaUI *ui,
+ Window frame_xwindow,
+ int *top_height, int *bottom_height,
+ int *left_width, int *right_width)
+{
+ meta_frames_get_geometry (ui->frames, frame_xwindow,
+ top_height, bottom_height,
+ left_width, right_width);
+}
+
+
+void
+meta_ui_add_frame (MetaUI *ui,
+ Window xwindow)
+{
+ meta_frames_manage_window (ui->frames, xwindow);
+}
+
+void
+meta_ui_remove_frame (MetaUI *ui,
+ Window xwindow)
+{
+ meta_frames_unmanage_window (ui->frames, xwindow);
+}
+
+void
+meta_ui_reset_frame_bg (MetaUI *ui,
+ Window xwindow)
+{
+ meta_frames_reset_bg (ui->frames, xwindow);
+}
+
+void
+meta_ui_set_frame_flags (MetaUI *ui,
+ Window xwindow,
+ MetaFrameFlags flags)
+{
+ meta_frames_set_flags (ui->frames, xwindow, flags);
+}
+
+void
+meta_ui_queue_frame_draw (MetaUI *ui,
+ Window xwindow)
+{
+ meta_frames_queue_draw (ui->frames, xwindow);
+}
+
+
+
diff --git a/src/ui.h b/src/ui.h
index 4e2260e37..17c843955 100644
--- a/src/ui.h
+++ b/src/ui.h
@@ -29,8 +29,28 @@ typedef struct _MetaUI MetaUI;
void meta_ui_init (int *argc, char ***argv);
-MetaUI* meta_ui_new (Display *xdisplay);
+MetaUI* meta_ui_new (Display *xdisplay,
+ Screen *screen);
void meta_ui_free (MetaUI *ui);
+void meta_ui_get_frame_geometry (MetaUI *ui,
+ Window frame_xwindow,
+ int *top_height, int *bottom_height,
+ int *left_width, int *right_width);
+void meta_ui_add_frame (MetaUI *ui,
+ Window xwindow);
+void meta_ui_remove_frame (MetaUI *ui,
+ Window xwindow);
+
+
+void meta_ui_reset_frame_bg (MetaUI *ui,
+ Window xwindow);
+
+void meta_ui_set_frame_flags (MetaUI *ui,
+ Window xwindow,
+ MetaFrameFlags flags);
+
+void meta_ui_queue_frame_draw (MetaUI *ui,
+ Window xwindow);
#endif
diff --git a/src/window.c b/src/window.c
index 927b1f3f7..51e536609 100644
--- a/src/window.c
+++ b/src/window.c
@@ -802,8 +802,6 @@ meta_window_move_resize_internal (MetaWindow *window,
*/
if (window->frame)
meta_frame_calc_geometry (window->frame,
- window->rect.width,
- window->rect.height,
&fgeom);
constrain_size (window, &fgeom, w, h, &w, &h);