From 92feea3033ee5ff2f4a6855eb481d4d2287e7cf9 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 9 Sep 2022 16:10:15 +0200 Subject: [PATCH] ui: Excise old frames UI This is no longer used, in favor of the standalone frames client. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1077 Part-of: --- src/backends/meta-settings.c | 1 - src/core/restart.c | 1 - src/core/window.c | 1 - src/meson.build | 6 - src/meta/meson.build | 1 - src/meta/theme.h | 41 - src/tests/test-runner.c | 8 - src/ui/frames.c | 1927 ---------------------------- src/ui/frames.h | 155 --- src/ui/theme-private.h | 281 ---- src/ui/theme.c | 1358 -------------------- src/ui/ui.c | 240 ---- src/ui/ui.h | 68 - src/x11/meta-x11-display-private.h | 3 - src/x11/xprops.c | 1 - 15 files changed, 4092 deletions(-) delete mode 100644 src/meta/theme.h delete mode 100644 src/ui/frames.c delete mode 100644 src/ui/frames.h delete mode 100644 src/ui/theme-private.h delete mode 100644 src/ui/theme.c delete mode 100644 src/ui/ui.c delete mode 100644 src/ui/ui.h diff --git a/src/backends/meta-settings.c b/src/backends/meta-settings.c index 2826ff98f..9ee930b8f 100644 --- a/src/backends/meta-settings.c +++ b/src/backends/meta-settings.c @@ -28,7 +28,6 @@ #include "backends/meta-backend-private.h" #include "backends/meta-logical-monitor.h" #include "backends/meta-monitor-manager-private.h" -#include "ui/theme-private.h" #ifndef XWAYLAND_GRAB_DEFAULT_ACCESS_RULES # warning "XWAYLAND_GRAB_DEFAULT_ACCESS_RULES is not set" diff --git a/src/core/restart.c b/src/core/restart.c index 14d0de934..cd8ba6872 100644 --- a/src/core/restart.c +++ b/src/core/restart.c @@ -42,7 +42,6 @@ #include "core/display-private.h" #include "core/util-private.h" #include "meta/main.h" -#include "ui/ui.h" #include "x11/meta-x11-display-private.h" static gboolean restart_helper_started = FALSE; diff --git a/src/core/window.c b/src/core/window.c index a5d203a5c..962c05f20 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -84,7 +84,6 @@ #include "meta/meta-enum-types.h" #include "meta/meta-x11-errors.h" #include "meta/prefs.h" -#include "ui/ui.h" #include "x11/meta-x11-display-private.h" #include "x11/window-props.h" #include "x11/window-x11.h" diff --git a/src/meson.build b/src/meson.build index 6a995f3d4..a97201367 100644 --- a/src/meson.build +++ b/src/meson.build @@ -447,12 +447,6 @@ if have_x11_client 'compositor/meta-sync-ring.h', 'compositor/meta-window-actor-x11.c', 'compositor/meta-window-actor-x11.h', - 'ui/frames.c', - 'ui/frames.h', - 'ui/theme.c', - 'ui/theme-private.h', - 'ui/ui.c', - 'ui/ui.h', 'x11/atomnames.h', 'x11/events.c', 'x11/events.h', diff --git a/src/meta/meson.build b/src/meta/meson.build index 3076f7532..94b385310 100644 --- a/src/meta/meson.build +++ b/src/meta/meson.build @@ -40,7 +40,6 @@ mutter_public_headers = [ 'meta-window-shape.h', 'meta-workspace-manager.h', 'prefs.h', - 'theme.h', 'types.h', 'util.h', 'window.h', diff --git a/src/meta/theme.h b/src/meta/theme.h deleted file mode 100644 index 0fbd1e5af..000000000 --- a/src/meta/theme.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Metacity Theme Rendering */ - -/* - * 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, see . - */ - -#ifndef META_THEME_H -#define META_THEME_H - -#include - -/** - * MetaTheme: - * - */ -typedef struct _MetaTheme MetaTheme; - -META_EXPORT -MetaTheme* meta_theme_get_default (void); - -META_EXPORT -MetaTheme* meta_theme_new (void); - -META_EXPORT -void meta_theme_free (MetaTheme *theme); -#endif diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c index bf08304e8..52dc7ec65 100644 --- a/src/tests/test-runner.c +++ b/src/tests/test-runner.c @@ -31,7 +31,6 @@ #include "meta/window.h" #include "core/meta-workspace-manager-private.h" #include "tests/meta-test-utils.h" -#include "ui/ui.h" #include "wayland/meta-wayland.h" #include "x11/meta-x11-display-private.h" @@ -241,13 +240,6 @@ test_case_assert_stacking (TestCase *test, if (window != NULL && window->title) { - /* See comment in meta_ui_new() about why the dummy window for GTK+ theming - * is managed as a MetaWindow. - */ - if (META_STACK_ID_IS_X11 (windows[i]) && - meta_ui_window_is_dummy (display->x11_display->ui, windows[i])) - continue; - if (stack_string->len > 0) g_string_append_c (stack_string, ' '); diff --git a/src/ui/frames.c b/src/ui/frames.c deleted file mode 100644 index e1fb6e502..000000000 --- a/src/ui/frames.c +++ /dev/null @@ -1,1927 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Metacity window frame manager widget */ - -/* - * Copyright (C) 2001 Havoc Pennington - * Copyright (C) 2003 Red Hat, Inc. - * Copyright (C) 2005, 2006 Elijah Newren - * - * 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, see . - */ - -#include "config.h" - -#include -#include -#include -#include - -#include "core/frame.h" -#include "core/window-private.h" -#include "meta/boxes.h" -#include "meta/prefs.h" -#include "meta/theme.h" -#include "meta/util.h" -#include "ui/ui.h" -#include "ui/frames.h" -#include "x11/meta-x11-window-control.h" -#include "x11/window-x11-private.h" -#include "x11/window-x11.h" - -#define DEFAULT_INNER_BUTTON_BORDER 3 - -static void meta_frames_destroy (GtkWidget *object); -static void meta_frames_finalize (GObject *object); -static void meta_frames_style_updated (GtkWidget *widget); - -static gboolean meta_frames_draw (GtkWidget *widget, - cairo_t *cr); - -static void meta_ui_frame_attach_style (MetaUIFrame *frame); - -static void meta_ui_frame_paint (MetaUIFrame *frame, - cairo_t *cr); - -static void meta_ui_frame_calc_geometry (MetaUIFrame *frame, - MetaFrameGeometry *fgeom); - -static void meta_ui_frame_update_prelit_control (MetaUIFrame *frame, - MetaFrameControl control); - -static void meta_frames_font_changed (MetaFrames *frames); -static void meta_frames_button_layout_changed (MetaFrames *frames); -static void meta_frames_reattach_all_styles (MetaFrames *frames); - - -static GdkRectangle* control_rect (MetaFrameControl control, - MetaFrameGeometry *fgeom); -static MetaFrameControl get_control (MetaUIFrame *frame, - int x, - int y); - -G_DEFINE_TYPE (MetaFrames, meta_frames, GTK_TYPE_WINDOW); - -enum -{ - META_ACTION_CLICK, - META_ACTION_RIGHT_CLICK, - META_ACTION_MIDDLE_CLICK, - META_ACTION_DOUBLE_CLICK, - META_ACTION_IGNORE -}; - -static GObject * -meta_frames_constructor (GType gtype, - guint n_properties, - GObjectConstructParam *properties) -{ - GObject *object; - GObjectClass *gobject_class; - - gobject_class = G_OBJECT_CLASS (meta_frames_parent_class); - object = gobject_class->constructor (gtype, n_properties, properties); - - g_object_set (object, - "type", GTK_WINDOW_POPUP, - NULL); - - return object; -} - -static void -meta_frames_class_init (MetaFramesClass *class) -{ - GObjectClass *gobject_class; - GtkWidgetClass *widget_class; - - gobject_class = G_OBJECT_CLASS (class); - widget_class = (GtkWidgetClass*) class; - - gobject_class->constructor = meta_frames_constructor; - gobject_class->finalize = meta_frames_finalize; - - widget_class->destroy = meta_frames_destroy; - - widget_class->style_updated = meta_frames_style_updated; - - widget_class->draw = meta_frames_draw; -} - -static gint -unsigned_long_equal (gconstpointer v1, - gconstpointer v2) -{ - return *((const gulong*) v1) == *((const gulong*) v2); -} - -static guint -unsigned_long_hash (gconstpointer v) -{ - gulong val = * (const gulong *) v; - - /* I'm not sure this works so well. */ -#if GLIB_SIZEOF_LONG > 4 - return (guint) (val ^ (val >> 32)); -#else - return val; -#endif -} - -static void -prefs_changed_callback (MetaPreference pref, - void *data) -{ - switch (pref) - { - case META_PREF_TITLEBAR_FONT: - meta_frames_font_changed (META_FRAMES (data)); - break; - case META_PREF_BUTTON_LAYOUT: - meta_frames_button_layout_changed (META_FRAMES (data)); - break; - default: - break; - } -} - -static void -invalidate_whole_window (MetaUIFrame *frame) -{ - if (!frame->is_frozen) - { - meta_window_x11_freeze_commits (frame->meta_window); - frame->is_frozen = TRUE; - } - gdk_window_invalidate_rect (frame->window, NULL, FALSE); -} - -static MetaStyleInfo * -meta_frames_get_theme_variant (MetaFrames *frames, - const gchar *variant) -{ - MetaStyleInfo *style_info; - - style_info = g_hash_table_lookup (frames->style_variants, variant); - if (style_info == NULL) - { - style_info = meta_theme_create_style_info (gtk_widget_get_screen (GTK_WIDGET (frames)), variant); - g_hash_table_insert (frames->style_variants, g_strdup (variant), style_info); - } - - return style_info; -} - -static void -update_style_contexts (MetaFrames *frames) -{ - MetaStyleInfo *style_info; - GList *variants, *variant; - GdkScreen *screen; - - screen = gtk_widget_get_screen (GTK_WIDGET (frames)); - - if (frames->normal_style) - meta_style_info_unref (frames->normal_style); - frames->normal_style = meta_theme_create_style_info (screen, NULL); - - variants = g_hash_table_get_keys (frames->style_variants); - for (variant = variants; variant; variant = variant->next) - { - style_info = meta_theme_create_style_info (screen, (char *)variant->data); - g_hash_table_insert (frames->style_variants, - g_strdup (variant->data), style_info); - } - g_list_free (variants); -} - -static void -meta_frames_init (MetaFrames *frames) -{ - frames->interface_settings = g_settings_new ("org.gnome.desktop.interface"); - g_signal_connect_swapped (frames->interface_settings, - "changed::color-scheme", - G_CALLBACK (meta_frames_reattach_all_styles), - frames); - - frames->text_heights = g_hash_table_new (NULL, NULL); - - frames->frames = g_hash_table_new (unsigned_long_hash, unsigned_long_equal); - - frames->style_variants = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify)meta_style_info_unref); - - update_style_contexts (frames); - - meta_prefs_add_listener (prefs_changed_callback, frames); -} - -static void -listify_func (gpointer key, gpointer value, gpointer data) -{ - GSList **listp; - - listp = data; - *listp = g_slist_prepend (*listp, value); -} - -static void -meta_frames_destroy (GtkWidget *object) -{ - GSList *winlist; - GSList *tmp; - MetaFrames *frames; - - frames = META_FRAMES (object); - - winlist = NULL; - g_hash_table_foreach (frames->frames, listify_func, &winlist); - - /* Unmanage all frames */ - for (tmp = winlist; tmp != NULL; tmp = tmp->next) - { - MetaUIFrame *frame = tmp->data; - meta_ui_frame_unmanage (frame); - } - g_slist_free (winlist); - - if (frames->normal_style) - { - meta_style_info_unref (frames->normal_style); - frames->normal_style = NULL; - } - - if (frames->style_variants) - { - g_hash_table_destroy (frames->style_variants); - frames->style_variants = NULL; - } - - g_clear_object (&frames->interface_settings); - - GTK_WIDGET_CLASS (meta_frames_parent_class)->destroy (object); -} - -static void -meta_frames_finalize (GObject *object) -{ - MetaFrames *frames; - - frames = META_FRAMES (object); - - meta_prefs_remove_listener (prefs_changed_callback, frames); - - g_hash_table_destroy (frames->text_heights); - - g_assert (g_hash_table_size (frames->frames) == 0); - g_hash_table_destroy (frames->frames); - - G_OBJECT_CLASS (meta_frames_parent_class)->finalize (object); -} - -static void -queue_recalc_func (gpointer key, - gpointer value, - gpointer user_data) -{ - MetaUIFrame *frame = value; - MetaFrames *frames = user_data; - - invalidate_whole_window (frame); - meta_x11_wm_queue_frame_resize (frames->x11_display, - frame->xwindow); - - g_clear_object (&frame->text_layout); -} - -static void -meta_frames_font_changed (MetaFrames *frames) -{ - if (g_hash_table_size (frames->text_heights) > 0) - { - g_hash_table_destroy (frames->text_heights); - frames->text_heights = g_hash_table_new (NULL, NULL); - } - - /* Queue a draw/resize on all frames */ - g_hash_table_foreach (frames->frames, - queue_recalc_func, frames); - -} - -static void -queue_draw_func (gpointer key, gpointer value, gpointer data) -{ - MetaUIFrame *frame = value; - invalidate_whole_window (frame); -} - -static void -meta_frames_button_layout_changed (MetaFrames *frames) -{ - g_hash_table_foreach (frames->frames, - queue_draw_func, frames); -} - -static void -reattach_style_func (gpointer key, gpointer value, gpointer data) -{ - MetaUIFrame *frame = value; - meta_ui_frame_attach_style (frame); -} - -static void -meta_frames_reattach_all_styles (MetaFrames *frames) -{ - g_hash_table_foreach (frames->frames, reattach_style_func, NULL); - meta_display_queue_retheme_all_windows (meta_get_display ()); -} - -static void -meta_frames_style_updated (GtkWidget *widget) -{ - MetaFrames *frames; - - frames = META_FRAMES (widget); - - meta_frames_font_changed (frames); - - update_style_contexts (frames); - - meta_frames_reattach_all_styles (frames); - - GTK_WIDGET_CLASS (meta_frames_parent_class)->style_updated (widget); -} - -static void -meta_ui_frame_ensure_layout (MetaUIFrame *frame, - MetaFrameType type) -{ - MetaFrames *frames = frame->frames; - GtkWidget *widget; - MetaFrameLayout *layout; - - widget = GTK_WIDGET (frames); - - g_return_if_fail (gtk_widget_get_realized (widget)); - - layout = meta_theme_get_frame_layout (meta_theme_get_default (), type); - - if (layout != frame->cache_layout) - g_clear_object (&frame->text_layout); - - frame->cache_layout = layout; - - if (frame->text_layout == NULL) - { - gpointer key, value; - PangoFontDescription *font_desc; - int size; - - frame->text_layout = gtk_widget_create_pango_layout (widget, frame->title); - - pango_layout_set_ellipsize (frame->text_layout, PANGO_ELLIPSIZE_END); - pango_layout_set_auto_dir (frame->text_layout, FALSE); - pango_layout_set_single_paragraph_mode (frame->text_layout, TRUE); - - font_desc = meta_style_info_create_font_desc (frame->style_info); - meta_frame_layout_apply_scale (layout, font_desc); - - size = pango_font_description_get_size (font_desc); - - if (g_hash_table_lookup_extended (frames->text_heights, - GINT_TO_POINTER (size), - &key, &value)) - { - frame->text_height = GPOINTER_TO_INT (value); - } - else - { - frame->text_height = - meta_pango_font_desc_get_text_height (font_desc, - gtk_widget_get_pango_context (widget)); - - g_hash_table_replace (frames->text_heights, - GINT_TO_POINTER (size), - GINT_TO_POINTER (frame->text_height)); - } - - pango_layout_set_font_description (frame->text_layout, - font_desc); - - pango_font_description_free (font_desc); - } -} - -static void -meta_ui_frame_calc_geometry (MetaUIFrame *frame, - MetaFrameGeometry *fgeom) -{ - MetaFrameFlags flags; - MetaFrameType type; - MetaButtonLayout button_layout; - MetaWindowX11 *window_x11 = META_WINDOW_X11 (frame->meta_window); - MetaRectangle client_rect; - - flags = meta_frame_get_flags (frame->meta_window->frame); - type = meta_window_get_frame_type (frame->meta_window); - - meta_ui_frame_ensure_layout (frame, type); - - meta_prefs_get_button_layout (&button_layout); - - client_rect = meta_window_x11_get_client_rect (window_x11); - - meta_theme_calc_geometry (meta_theme_get_default (), - frame->style_info, - type, - frame->text_height, - flags, - client_rect.width, - client_rect.height, - &button_layout, - fgeom); -} - -MetaFrames* -meta_frames_new (MetaX11Display *x11_display) -{ - MetaFrames *frames; - - frames = g_object_new (META_TYPE_FRAMES, - "type", GTK_WINDOW_POPUP, - NULL); - frames->x11_display = x11_display; - - /* Put the window at an arbitrary offscreen location; the one place - * it can't be is at -100x-100, since the meta_window_new() will - * mistake it for a window created via meta_create_offscreen_window() - * and ignore it, and we need this window to get frame-synchronization - * messages so that GTK+'s style change handling works. - */ - gtk_window_move (GTK_WINDOW (frames), -200, -200); - gtk_window_resize (GTK_WINDOW (frames), 1, 1); - - return frames; -} - -static const char * -get_global_theme_variant (MetaFrames *frames) -{ - GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (frames)); - GtkSettings *settings = gtk_settings_get_for_screen (screen); - gboolean dark_theme_requested; - - g_object_get (settings, - "gtk-application-prefer-dark-theme", &dark_theme_requested, - NULL); - - if (dark_theme_requested) - return "dark"; - - return NULL; -} - -static const char * -get_color_scheme_variant (MetaFrames *frames) -{ - int color_scheme = g_settings_get_enum (frames->interface_settings, "color-scheme"); - - if (color_scheme == G_DESKTOP_COLOR_SCHEME_PREFER_DARK) - return "dark"; - - return NULL; -} - -/* In order to use a style with a window it has to be attached to that - * window. Actually, the colormaps just have to match, but since GTK+ - * already takes care of making sure that its cheap to attach a style - * to multiple windows with the same colormap, we can just go ahead - * and attach separately for each window. - */ -static void -meta_ui_frame_attach_style (MetaUIFrame *frame) -{ - MetaFrames *frames = frame->frames; - const char *variant; - - if (frame->style_info != NULL) - meta_style_info_unref (frame->style_info); - - variant = frame->meta_window->gtk_theme_variant; - if (variant == NULL) - variant = get_global_theme_variant (frame->frames); - if (variant == NULL) - variant = get_color_scheme_variant (frame->frames); - - if (variant == NULL || *variant == '\0') - frame->style_info = meta_style_info_ref (frames->normal_style); - else - frame->style_info = meta_style_info_ref (meta_frames_get_theme_variant (frames, - variant)); -} - -MetaUIFrame * -meta_frames_manage_window (MetaFrames *frames, - MetaWindow *meta_window, - Window xwindow, - GdkWindow *window) -{ - MetaUIFrame *frame; - - g_assert (window); - - frame = g_new (MetaUIFrame, 1); - - frame->frames = frames; - frame->window = window; - - gdk_window_set_user_data (frame->window, frames); - - frame->style_info = NULL; - - /* Don't set event mask here, it's in frame.c */ - - frame->xwindow = xwindow; - frame->meta_window = meta_window; - frame->cache_layout = NULL; - frame->text_layout = NULL; - frame->text_height = -1; - frame->title = NULL; - frame->prelit_control = META_FRAME_CONTROL_NONE; - frame->button_state = META_BUTTON_STATE_NORMAL; - frame->is_frozen = FALSE; - - meta_x11_wm_grab_buttons (frames->x11_display, frame->xwindow); - - g_hash_table_replace (frames->frames, &frame->xwindow, frame); - - return frame; -} - -void -meta_ui_frame_unmanage (MetaUIFrame *frame) -{ - MetaFrames *frames = frame->frames; - - /* restore the cursor */ - meta_x11_wm_set_screen_cursor (frames->x11_display, - frame->xwindow, - META_CURSOR_DEFAULT); - - gdk_window_set_user_data (frame->window, NULL); - - g_hash_table_remove (frames->frames, &frame->xwindow); - - meta_style_info_unref (frame->style_info); - - gdk_window_destroy (frame->window); - - if (frame->text_layout) - g_object_unref (G_OBJECT (frame->text_layout)); - - if (frame->is_frozen) - meta_window_x11_thaw_commits (frame->meta_window); - - g_free (frame->title); - - g_free (frame); -} - -void -meta_ui_frame_get_borders (MetaUIFrame *frame, - MetaFrameBorders *borders) -{ - MetaFrameFlags flags; - MetaFrameType type; - - flags = meta_frame_get_flags (frame->meta_window->frame); - type = meta_window_get_frame_type (frame->meta_window); - - g_return_if_fail (type < META_FRAME_TYPE_LAST); - - meta_ui_frame_ensure_layout (frame, type); - - /* We can't get the full geometry, because that depends on - * the client window size and probably we're being called - * by the core move/resize code to decide on the client - * window size - */ - meta_theme_get_frame_borders (meta_theme_get_default (), - frame->style_info, - type, - frame->text_height, - flags, - borders); -} - -/* The visible frame rectangle surrounds the visible portion of the - * frame window; it subtracts only the invisible borders from the frame - * window's size. - */ -static void -get_visible_frame_rect (MetaFrameGeometry *fgeom, - cairo_rectangle_int_t *rect) -{ - rect->x = fgeom->borders.invisible.left; - rect->y = fgeom->borders.invisible.top; - rect->width = fgeom->width - fgeom->borders.invisible.right - rect->x; - rect->height = fgeom->height - fgeom->borders.invisible.bottom - rect->y; -} - -static cairo_region_t * -get_visible_region (MetaUIFrame *frame, - MetaFrameGeometry *fgeom) -{ - cairo_region_t *corners_region; - cairo_region_t *visible_region; - cairo_rectangle_int_t rect; - cairo_rectangle_int_t frame_rect; - - corners_region = cairo_region_create (); - get_visible_frame_rect (fgeom, &frame_rect); - - if (fgeom->top_left_corner_rounded_radius != 0) - { - const int corner = fgeom->top_left_corner_rounded_radius; - const float radius = corner; - int i; - - for (i=0; itop_right_corner_rounded_radius != 0) - { - const int corner = fgeom->top_right_corner_rounded_radius; - const float radius = corner; - int i; - - for (i=0; ibottom_left_corner_rounded_radius != 0) - { - const int corner = fgeom->bottom_left_corner_rounded_radius; - const float radius = corner; - int i; - - for (i=0; ibottom_right_corner_rounded_radius != 0) - { - const int corner = fgeom->bottom_right_corner_rounded_radius; - const float radius = corner; - int i; - - for (i=0; iwindow); - old_height = gdk_window_get_height (frame->window); - - gdk_window_move_resize (frame->window, x, y, width, height); - - if (old_width != width || old_height != height) - invalidate_whole_window (frame); -} - -void -meta_ui_frame_queue_draw (MetaUIFrame *frame) -{ - invalidate_whole_window (frame); -} - -void -meta_ui_frame_set_title (MetaUIFrame *frame, - const char *title) -{ - g_free (frame->title); - frame->title = g_strdup (title); - - g_clear_object (&frame->text_layout); - - invalidate_whole_window (frame); -} - -void -meta_ui_frame_update_style (MetaUIFrame *frame) -{ - meta_ui_frame_attach_style (frame); - invalidate_whole_window (frame); -} - -static void -redraw_control (MetaUIFrame *frame, - MetaFrameControl control) -{ - MetaFrameGeometry fgeom; - GdkRectangle *rect; - - meta_ui_frame_calc_geometry (frame, &fgeom); - - rect = control_rect (control, &fgeom); - - gdk_window_invalidate_rect (frame->window, rect, FALSE); -} - -static gboolean -meta_frame_titlebar_event (MetaUIFrame *frame, - const ClutterEvent *event, - int action) -{ - MetaFrameFlags flags; - MetaX11Display *x11_display; - uint32_t evtime; - float x, y; - - g_assert (event->type == CLUTTER_BUTTON_PRESS || - event->type == CLUTTER_TOUCH_BEGIN); - - x11_display = frame->frames->x11_display; - - flags = meta_frame_get_flags (frame->meta_window->frame); - - evtime = clutter_event_get_time (event); - clutter_event_get_coords (event, &x, &y); - - switch (action) - { - case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_SHADE: - { - if (flags & META_FRAME_ALLOWS_SHADE) - { - if (flags & META_FRAME_SHADED) - meta_window_unshade (frame->meta_window, evtime); - else - meta_window_shade (frame->meta_window, evtime); - } - } - break; - - case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE: - { - if (flags & META_FRAME_ALLOWS_MAXIMIZE) - { - meta_x11_wm_toggle_maximize (x11_display, frame->xwindow); - } - } - break; - - case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_HORIZONTALLY: - { - if (flags & META_FRAME_ALLOWS_MAXIMIZE) - { - meta_x11_wm_toggle_maximize_horizontally (x11_display, - frame->xwindow); - } - } - break; - - case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_VERTICALLY: - { - if (flags & META_FRAME_ALLOWS_MAXIMIZE) - { - meta_x11_wm_toggle_maximize_vertically (x11_display, frame->xwindow); - } - } - break; - - case G_DESKTOP_TITLEBAR_ACTION_MINIMIZE: - { - if (flags & META_FRAME_ALLOWS_MINIMIZE) - meta_window_minimize (frame->meta_window); - } - break; - - case G_DESKTOP_TITLEBAR_ACTION_NONE: - /* Yaay, a sane user that doesn't use that other weird crap! */ - break; - - case G_DESKTOP_TITLEBAR_ACTION_LOWER: - meta_x11_wm_user_lower_and_unfocus (x11_display, - frame->xwindow, - evtime); - break; - - case G_DESKTOP_TITLEBAR_ACTION_MENU: - meta_x11_wm_show_window_menu (x11_display, - frame->xwindow, - META_WINDOW_MENU_WM, - x, y, evtime); - break; - } - - return TRUE; -} - -static gboolean -meta_frame_double_click_event (MetaUIFrame *frame, - const ClutterEvent *event) -{ - int action = meta_prefs_get_action_double_click_titlebar (); - - return meta_frame_titlebar_event (frame, event, action); -} - -static gboolean -meta_frame_middle_click_event (MetaUIFrame *frame, - ClutterButtonEvent *event) -{ - int action = meta_prefs_get_action_middle_click_titlebar(); - - return meta_frame_titlebar_event (frame, (const ClutterEvent *) event, - action); -} - -static gboolean -meta_frame_right_click_event (MetaUIFrame *frame, - ClutterButtonEvent *event) -{ - int action = meta_prefs_get_action_right_click_titlebar(); - - return meta_frame_titlebar_event (frame, (const ClutterEvent *) event, - action); -} - -static gboolean -meta_frames_try_grab_op (MetaUIFrame *frame, - MetaGrabOp op, - gdouble grab_x, - gdouble grab_y, - guint32 time) -{ - MetaFrames *frames = frame->frames; - gboolean ret; - - ret = meta_x11_wm_begin_grab_op (frames->x11_display, - frame->xwindow, - op, - FALSE, - TRUE, - frame->grab_button, - 0, - time, - grab_x, grab_y); - if (!ret) - { - frames->current_grab_op = op; - frames->grab_frame = frame; - frames->grab_x = grab_x; - frames->grab_y = grab_y; - } - else - frames->grab_touch = NULL; - - return ret; -} - -static gboolean -meta_frames_retry_grab_op (MetaFrames *frames, - guint time) -{ - MetaGrabOp op; - gboolean ret; - - if (frames->current_grab_op == META_GRAB_OP_NONE) - return TRUE; - - op = frames->current_grab_op; - frames->current_grab_op = META_GRAB_OP_NONE; - - ret = meta_x11_wm_begin_grab_op (frames->x11_display, - frames->grab_frame->xwindow, - op, - FALSE, - TRUE, - frames->grab_frame->grab_button, - 0, - time, - frames->grab_x, - frames->grab_y); - if (ret) - frames->grab_touch = NULL; - - return ret; -} - -static MetaGrabOp -grab_op_from_resize_control (MetaFrameControl control) -{ - switch (control) - { - case META_FRAME_CONTROL_RESIZE_SE: - return META_GRAB_OP_RESIZING_SE; - case META_FRAME_CONTROL_RESIZE_S: - return META_GRAB_OP_RESIZING_S; - case META_FRAME_CONTROL_RESIZE_SW: - return META_GRAB_OP_RESIZING_SW; - case META_FRAME_CONTROL_RESIZE_NE: - return META_GRAB_OP_RESIZING_NE; - case META_FRAME_CONTROL_RESIZE_N: - return META_GRAB_OP_RESIZING_N; - case META_FRAME_CONTROL_RESIZE_NW: - return META_GRAB_OP_RESIZING_NW; - case META_FRAME_CONTROL_RESIZE_E: - return META_GRAB_OP_RESIZING_E; - case META_FRAME_CONTROL_RESIZE_W: - return META_GRAB_OP_RESIZING_W; - default: - g_assert_not_reached (); - return META_GRAB_OP_NONE; - } -} - -static int -meta_ui_frame_update_click_count (MetaUIFrame *frame, - const ClutterEvent *event) -{ - MetaFrames *frames = frame->frames; - ClutterSettings *settings; - int double_click_time, double_click_distance; - uint32_t evtime; - float x, y; - - settings = clutter_settings_get_default (); - clutter_event_get_coords (event, &x, &y); - evtime = clutter_event_get_time (event); - - g_object_get (settings, - "double-click-distance", &double_click_distance, - "double-click-time", &double_click_time, - NULL); - - if (evtime > (frames->last_click_time + double_click_time) || - (ABS (x - frames->last_click_x) > double_click_distance) || - (ABS (y - frames->last_click_y) > double_click_distance)) - frames->click_count = 0; - - frames->last_click_time = evtime; - frames->last_click_x = x; - frames->last_click_y = y; - - frames->click_count = (frames->click_count % 2) + 1; - - return frames->click_count; -} - -static guint -get_action (MetaUIFrame *frame, - const ClutterEvent *event) -{ - if (event->type == CLUTTER_BUTTON_PRESS || - event->type == CLUTTER_BUTTON_RELEASE) - { - switch (event->button.button) - { - case CLUTTER_BUTTON_PRIMARY: - if (meta_ui_frame_update_click_count (frame, event) == 2) - return META_ACTION_DOUBLE_CLICK; - else - return META_ACTION_CLICK; - case CLUTTER_BUTTON_SECONDARY: - return META_ACTION_RIGHT_CLICK; - case CLUTTER_BUTTON_MIDDLE: - return META_ACTION_MIDDLE_CLICK; - default: - meta_verbose ("No action triggered for button %u %s", - event->button.button, - (event->type == CLUTTER_BUTTON_PRESS) ? "press" : "release"); - } - } - else if (event->type == CLUTTER_TOUCH_BEGIN || - event->type == CLUTTER_TOUCH_UPDATE || - event->type == CLUTTER_TOUCH_END) - { - return META_ACTION_CLICK; - } - - return META_ACTION_IGNORE; -} - -static uint32_t -get_button_number (const ClutterEvent *event) -{ - if (event->type == CLUTTER_TOUCH_BEGIN || - event->type == CLUTTER_TOUCH_UPDATE || - event->type == CLUTTER_TOUCH_END) - return -1; - else if (event->type == CLUTTER_BUTTON_PRESS || - event->type == CLUTTER_BUTTON_RELEASE) - return clutter_event_get_button (event); - - g_assert_not_reached (); - return -1; -} - -static gboolean -meta_frame_left_click_event (MetaUIFrame *frame, - const ClutterEvent *event) -{ - MetaX11Display *x11_display = frame->frames->x11_display; - MetaFrameControl control; - guint32 evtime; - gfloat x, y; - - evtime = clutter_event_get_time (event); - clutter_event_get_coords (event, &x, &y); - control = get_control (frame, x, y); - - switch (control) - { - case META_FRAME_CONTROL_MAXIMIZE: - case META_FRAME_CONTROL_UNMAXIMIZE: - case META_FRAME_CONTROL_MINIMIZE: - case META_FRAME_CONTROL_DELETE: - case META_FRAME_CONTROL_MENU: - frame->grab_button = get_button_number (event); - frame->button_state = META_BUTTON_STATE_PRESSED; - frame->prelit_control = control; - redraw_control (frame, control); - - if (control == META_FRAME_CONTROL_MENU) - { - MetaFrameGeometry fgeom; - GdkRectangle *rect; - MetaRectangle root_rect; - int win_x, win_y; - - meta_ui_frame_calc_geometry (frame, &fgeom); - - rect = control_rect (control, &fgeom); - - gdk_window_get_position (frame->window, &win_x, &win_y); - - root_rect.x = win_x + rect->x; - root_rect.y = win_y + rect->y; - root_rect.width = rect->width; - root_rect.height = rect->height; - - /* if the compositor takes a grab for showing the menu, we will - * get a LeaveNotify event we want to ignore, to keep the pressed - * button state while the menu is open - */ - frame->maybe_ignore_leave_notify = TRUE; - meta_x11_wm_show_window_menu_for_rect (x11_display, - frame->xwindow, - META_WINDOW_MENU_WM, - &root_rect, - evtime); - } - else - { - meta_frames_try_grab_op (frame, META_GRAB_OP_FRAME_BUTTON, - x, y, evtime); - } - - return TRUE; - case META_FRAME_CONTROL_RESIZE_SE: - case META_FRAME_CONTROL_RESIZE_S: - case META_FRAME_CONTROL_RESIZE_SW: - case META_FRAME_CONTROL_RESIZE_NE: - case META_FRAME_CONTROL_RESIZE_N: - case META_FRAME_CONTROL_RESIZE_NW: - case META_FRAME_CONTROL_RESIZE_E: - case META_FRAME_CONTROL_RESIZE_W: - meta_frames_try_grab_op (frame, - grab_op_from_resize_control (control), - x, y, evtime); - - return TRUE; - case META_FRAME_CONTROL_TITLE: - { - MetaFrameFlags flags = meta_frame_get_flags (frame->meta_window->frame); - - if (flags & META_FRAME_ALLOWS_MOVE) - { - meta_frames_try_grab_op (frame, - META_GRAB_OP_MOVING, - x, y, evtime); - } - } - - return TRUE; - case META_FRAME_CONTROL_NONE: - /* We can get this for example when trying to resize window - * that cannot be resized (e. g. it is maximized and the theme - * currently used has borders for maximized windows), see #751884 */ - return FALSE; - case META_FRAME_CONTROL_CLIENT_AREA: - /* This can happen with broken gtk themes that have a larger shadow size - * in the unfocused state than in the focused one. Then when clicking - * below the titlebar area in the unfocused state would still be - * considered a click on the titlebar due to it being shifted down because - * of the shadow. This then causes the window to be focused before this - * function is called, which removes the shadow such that the same - * position is now considered to be on the client area */ - return FALSE; - default: - g_assert_not_reached (); - return FALSE; - } -} - -static gboolean -handle_press_event (MetaUIFrame *frame, - const ClutterEvent *event) -{ - MetaFrameControl control; - uint32_t evtime, action; - float x, y; - - g_assert (event->type == CLUTTER_BUTTON_PRESS || - event->type == CLUTTER_TOUCH_BEGIN); - - action = get_action (frame, event); - if (action == META_ACTION_IGNORE) - return FALSE; - - evtime = clutter_event_get_time (event); - clutter_event_get_coords (event, &x, &y); - control = get_control (frame, x, y); - /* don't do the rest of this if on client area */ - if (control == META_FRAME_CONTROL_CLIENT_AREA) - return FALSE; /* not on the frame, just passed through from client */ - - if (action == META_ACTION_CLICK && - !(control == META_FRAME_CONTROL_MINIMIZE || - control == META_FRAME_CONTROL_DELETE || - control == META_FRAME_CONTROL_MAXIMIZE)) - { - meta_topic (META_DEBUG_FOCUS, - "Focusing window with frame 0x%lx due to button 1 press", - frame->xwindow); - meta_window_focus (frame->meta_window, evtime); - } - - /* We want to shade even if we have a GrabOp, since we'll have a move grab - * if we double click the titlebar. - */ - if (control == META_FRAME_CONTROL_TITLE && - action == META_ACTION_DOUBLE_CLICK) - { - meta_x11_wm_end_grab_op (frame->frames->x11_display, evtime); - return meta_frame_double_click_event (frame, event); - } - - if (meta_x11_wm_get_grab_op (frame->frames->x11_display) != META_GRAB_OP_NONE) - return FALSE; /* already up to something */ - - frame->grab_button = get_button_number (event); - - switch (action) - { - case META_ACTION_CLICK: - return meta_frame_left_click_event (frame, event); - case META_ACTION_MIDDLE_CLICK: - return meta_frame_middle_click_event (frame, (ClutterButtonEvent *) event); - case META_ACTION_RIGHT_CLICK: - return meta_frame_right_click_event (frame, (ClutterButtonEvent *) event); - default: - return FALSE; - } -} - -static gboolean -handle_release_event (MetaUIFrame *frame, - const ClutterEvent *event) -{ - guint32 evtime, button; - gfloat x, y; - - g_assert (event->type == CLUTTER_BUTTON_RELEASE || - event->type == CLUTTER_TOUCH_END); - - evtime = clutter_event_get_time (event); - clutter_event_get_coords (event, &x, &y); - button = get_button_number (event); - - frame->frames->current_grab_op = META_GRAB_OP_NONE; - meta_x11_wm_end_grab_op (frame->frames->x11_display, evtime); - - /* We only handle the releases we handled the presses for (things - * involving frame controls). Window ops that don't require a - * frame are handled in the Xlib part of the code, display.c/window.c - */ - if (((int) button) == frame->grab_button && - frame->button_state == META_BUTTON_STATE_PRESSED) - { - switch (frame->prelit_control) - { - case META_FRAME_CONTROL_MINIMIZE: - meta_window_minimize (frame->meta_window); - break; - case META_FRAME_CONTROL_MAXIMIZE: - /* Focus the window on the maximize */ - meta_window_focus (frame->meta_window, evtime); - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (frame->meta_window); - meta_window_maximize (frame->meta_window, META_MAXIMIZE_BOTH); - break; - case META_FRAME_CONTROL_UNMAXIMIZE: - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (frame->meta_window); - meta_window_unmaximize (frame->meta_window, META_MAXIMIZE_BOTH); - break; - case META_FRAME_CONTROL_DELETE: - meta_window_delete (frame->meta_window, evtime); - break; - default: - break; - } - - /* Update the prelit control regardless of what button the mouse - * was released over; needed so that the new button can become - * prelit so to let the user know that it can now be pressed. - * :) - */ - MetaFrameControl control = get_control (frame, x, y); - meta_ui_frame_update_prelit_control (frame, control); - } - - return TRUE; -} - -static void -meta_ui_frame_update_prelit_control (MetaUIFrame *frame, - MetaFrameControl control) -{ - MetaFrameControl old_control; - MetaCursor cursor; - - meta_verbose ("Updating prelit control from %u to %u", - frame->prelit_control, control); - - cursor = META_CURSOR_DEFAULT; - - switch (control) - { - case META_FRAME_CONTROL_CLIENT_AREA: - break; - case META_FRAME_CONTROL_NONE: - break; - case META_FRAME_CONTROL_TITLE: - break; - case META_FRAME_CONTROL_DELETE: - break; - case META_FRAME_CONTROL_MENU: - break; - case META_FRAME_CONTROL_MINIMIZE: - break; - case META_FRAME_CONTROL_MAXIMIZE: - break; - case META_FRAME_CONTROL_UNMAXIMIZE: - break; - case META_FRAME_CONTROL_RESIZE_SE: - cursor = META_CURSOR_SE_RESIZE; - break; - case META_FRAME_CONTROL_RESIZE_S: - cursor = META_CURSOR_SOUTH_RESIZE; - break; - case META_FRAME_CONTROL_RESIZE_SW: - cursor = META_CURSOR_SW_RESIZE; - break; - case META_FRAME_CONTROL_RESIZE_N: - cursor = META_CURSOR_NORTH_RESIZE; - break; - case META_FRAME_CONTROL_RESIZE_NE: - cursor = META_CURSOR_NE_RESIZE; - break; - case META_FRAME_CONTROL_RESIZE_NW: - cursor = META_CURSOR_NW_RESIZE; - break; - case META_FRAME_CONTROL_RESIZE_W: - cursor = META_CURSOR_WEST_RESIZE; - break; - case META_FRAME_CONTROL_RESIZE_E: - cursor = META_CURSOR_EAST_RESIZE; - break; - } - - /* set/unset the prelight cursor */ - meta_x11_wm_set_screen_cursor (frame->frames->x11_display, - frame->xwindow, - cursor); - - switch (control) - { - case META_FRAME_CONTROL_MENU: - case META_FRAME_CONTROL_MINIMIZE: - case META_FRAME_CONTROL_MAXIMIZE: - case META_FRAME_CONTROL_DELETE: - case META_FRAME_CONTROL_UNMAXIMIZE: - /* leave control set */ - break; - default: - /* Only prelight buttons */ - control = META_FRAME_CONTROL_NONE; - break; - } - - if (control == frame->prelit_control && - frame->button_state == META_BUTTON_STATE_PRELIGHT) - return; - - /* Save the old control so we can unprelight it */ - old_control = frame->prelit_control; - - frame->button_state = META_BUTTON_STATE_PRELIGHT; - frame->prelit_control = control; - - redraw_control (frame, old_control); - redraw_control (frame, control); -} - -static gboolean -handle_motion_event (MetaUIFrame *frame, - const ClutterEvent *event) -{ - MetaFrames *frames = frame->frames; - MetaFrameControl control; - ClutterModifierType modifiers; - guint32 evtime; - gfloat x, y; - - g_assert (event->type == CLUTTER_MOTION || - event->type == CLUTTER_TOUCH_UPDATE); - - modifiers = clutter_event_get_state (event); - evtime = clutter_event_get_time (event); - clutter_event_get_coords (event, &x, &y); - control = get_control (frame, x, y); - - if (frame->button_state == META_BUTTON_STATE_PRESSED) - { - /* If the user leaves the frame button, set the state - * back to normal and redraw. */ - if (frame->prelit_control != control) - { - frame->button_state = META_BUTTON_STATE_NORMAL; - redraw_control (frame, frame->prelit_control); - } - } - else - { - /* Update prelit control and cursor */ - meta_ui_frame_update_prelit_control (frame, control); - } - - if (frames->current_grab_op != META_GRAB_OP_NONE && - (event->type == CLUTTER_TOUCH_UPDATE || - (event->type == CLUTTER_MOTION && - (modifiers & CLUTTER_BUTTON1_MASK)))) - meta_frames_retry_grab_op (frames, evtime); - - return TRUE; -} - -static cairo_region_t * -get_visible_frame_border_region (MetaUIFrame *frame) -{ - cairo_rectangle_int_t area; - cairo_region_t *frame_border; - MetaFrameFlags flags; - MetaFrameType type; - MetaFrameBorders borders; - MetaRectangle buffer_rect = frame->meta_window->buffer_rect; - - flags = meta_frame_get_flags (frame->meta_window->frame); - type = meta_window_get_frame_type (frame->meta_window); - - meta_theme_get_frame_borders (meta_theme_get_default (), frame->style_info, - type, frame->text_height, flags, - &borders); - - /* Frame rect */ - area.x = 0; - area.y = 0; - area.width = buffer_rect.width; - area.height = buffer_rect.height; - - frame_border = cairo_region_create_rectangle (&area); - - /* Client rect */ - area.x += borders.total.left; - area.y += borders.total.top; - area.width -= borders.total.left + borders.total.right; - area.height -= borders.total.top + borders.total.bottom; - - /* Visible frame border */ - cairo_region_subtract_rectangle (frame_border, &area); - return frame_border; -} - -/* - * Draw the opaque and semi-opaque pixels of this frame into a mask. - * - * (0,0) in Cairo coordinates is assumed to be the top left corner of the - * invisible border. - * - * The parts of @cr's surface in the clip region are assumed to be - * initialized to fully-transparent, and the clip region is assumed to - * contain the invisible border and the visible parts of the frame, but - * not the client area. - * - * This function uses @cr to draw pixels of arbitrary color (it will - * typically be drawing in a %CAIRO_FORMAT_A8 surface, so the color is - * discarded anyway) with appropriate alpha values to reproduce this - * frame's alpha channel, as a mask to be applied to an opaque pixmap. - * - * @frame: This frame - * @frame_rect: The frame rect - * @cr: Used to draw the resulting mask - */ -void -meta_ui_frame_get_mask (MetaUIFrame *frame, - cairo_rectangle_int_t *frame_rect, - cairo_t *cr) -{ - MetaFrameBorders borders; - MetaFrameFlags flags; - cairo_surface_t *surface; - double xscale, yscale; - int scale; - - flags = meta_frame_get_flags (frame->meta_window->frame); - - meta_style_info_set_flags (frame->style_info, flags); - meta_ui_frame_get_borders (frame, &borders); - - /* See comment in meta_frame_layout_draw_with_style() for details on HiDPI handling */ - scale = meta_theme_get_window_scaling_factor (); - surface = cairo_get_target (cr); - cairo_surface_get_device_scale (surface, &xscale, &yscale); - cairo_surface_set_device_scale (surface, scale, scale); - - gtk_render_background (frame->style_info->styles[META_STYLE_ELEMENT_FRAME], cr, - borders.invisible.left / scale, - borders.invisible.top / scale, - frame_rect->width / scale, frame_rect->height / scale); - gtk_render_background (frame->style_info->styles[META_STYLE_ELEMENT_TITLEBAR], cr, - borders.invisible.left / scale, - borders.invisible.top / scale, - frame_rect->width / scale, borders.total.top / scale); - - cairo_surface_set_device_scale (surface, xscale, yscale); -} - -/* XXX -- this is disgusting. Find a better approach here. - * Use multiple widgets? */ -static MetaUIFrame * -find_frame_to_draw (MetaFrames *frames, - cairo_t *cr) -{ - GHashTableIter iter; - MetaUIFrame *frame; - - g_hash_table_iter_init (&iter, frames->frames); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &frame)) - if (gtk_cairo_should_draw_window (cr, frame->window)) - return frame; - - return NULL; -} - -static gboolean -meta_frames_draw (GtkWidget *widget, - cairo_t *cr) -{ - MetaUIFrame *frame; - MetaFrames *frames; - cairo_region_t *region; - - frames = META_FRAMES (widget); - - frame = find_frame_to_draw (frames, cr); - if (frame == NULL) - return FALSE; - - region = get_visible_frame_border_region (frame); - gdk_cairo_region (cr, region); - cairo_clip (cr); - - /* The target may be cleared to black or transparent, depending - * on the frame's visual; we don't want decorations to appear - * differently when the theme's decorations aren't fully opaque, - * so clear to black first - */ - cairo_paint (cr); - - meta_ui_frame_paint (frame, cr); - cairo_region_destroy (region); - - return TRUE; -} - -static void -meta_ui_frame_paint (MetaUIFrame *frame, - cairo_t *cr) -{ - MetaFrameFlags flags; - MetaFrameType type; - cairo_surface_t *mini_icon; - MetaButtonState button_states[META_BUTTON_TYPE_LAST]; - int i; - int button_type = -1; - MetaButtonLayout button_layout; - MetaWindowX11 *window_x11 = META_WINDOW_X11 (frame->meta_window); - MetaRectangle client_rect; - - for (i = 0; i < META_BUTTON_TYPE_LAST; i++) - button_states[i] = META_BUTTON_STATE_NORMAL; - - /* Set prelight state */ - switch (frame->prelit_control) - { - case META_FRAME_CONTROL_MENU: - button_type = META_BUTTON_TYPE_MENU; - break; - case META_FRAME_CONTROL_MINIMIZE: - button_type = META_BUTTON_TYPE_MINIMIZE; - break; - case META_FRAME_CONTROL_MAXIMIZE: - button_type = META_BUTTON_TYPE_MAXIMIZE; - break; - case META_FRAME_CONTROL_UNMAXIMIZE: - button_type = META_BUTTON_TYPE_MAXIMIZE; - break; - case META_FRAME_CONTROL_DELETE: - button_type = META_BUTTON_TYPE_CLOSE; - break; - default: - break; - } - - if (button_type > -1) - button_states[button_type] = frame->button_state; - - mini_icon = meta_window_get_mini_icon (frame->meta_window); - flags = meta_frame_get_flags (frame->meta_window->frame); - type = meta_window_get_frame_type (frame->meta_window); - - meta_ui_frame_ensure_layout (frame, type); - - meta_prefs_get_button_layout (&button_layout); - - client_rect = meta_window_x11_get_client_rect (window_x11); - - meta_theme_draw_frame (meta_theme_get_default (), - frame->style_info, - cr, - type, - flags, - client_rect.width, - client_rect.height, - frame->text_layout, - frame->text_height, - &button_layout, - button_states, - mini_icon); - - if (frame->is_frozen) - { - meta_window_x11_thaw_commits (frame->meta_window); - frame->is_frozen = FALSE; - } -} - -static gboolean -handle_enter_notify_event (MetaUIFrame *frame, - ClutterCrossingEvent *event) -{ - MetaFrameControl control; - - frame->maybe_ignore_leave_notify = FALSE; - - control = get_control (frame, event->x, event->y); - meta_ui_frame_update_prelit_control (frame, control); - - return TRUE; -} - -static gboolean -handle_leave_notify_event (MetaUIFrame *frame, - ClutterCrossingEvent *event) -{ - /* ignore the first LeaveNotify event after opening a window menu - * if it is the result of a compositor grab - */ - frame->maybe_ignore_leave_notify = frame->maybe_ignore_leave_notify && - (event->flags & CLUTTER_EVENT_FLAG_GRAB_NOTIFY) != 0; - - if (frame->maybe_ignore_leave_notify) - return FALSE; - - meta_ui_frame_update_prelit_control (frame, META_FRAME_CONTROL_NONE); - - return TRUE; -} - -gboolean -meta_ui_frame_handle_event (MetaUIFrame *frame, - const ClutterEvent *event) -{ - if (event->type == CLUTTER_TOUCH_BEGIN || - event->type == CLUTTER_TOUCH_UPDATE || - event->type == CLUTTER_TOUCH_END) - { - ClutterEventSequence *sequence; - MetaFrames *frames = frame->frames; - - /* In X11, mutter sets up passive touch grabs which basically - * means we handle those events twice (once through the passive - * grab, and then through XISelectEvents). - * - * Receiving touch events here means we are going through the - * former, but passive grabs are exclusively for gesture - * recognition purposes. - * - * We do actually want this to happen though the regular event - * selection paths to avoid breaking internal state, which means - * we will get pointer events, because we don't select for XI_Touch*. - */ - if (!meta_is_wayland_compositor ()) - return FALSE; - - sequence = clutter_event_get_event_sequence (event); - - /* Lock onto a single touch */ - if (frames->grab_touch && frames->grab_touch != sequence) - return FALSE; - - if (event->type == CLUTTER_TOUCH_BEGIN) - frames->grab_touch = sequence; - else if (event->type == CLUTTER_TOUCH_END) - frames->grab_touch = NULL; - } - - switch (event->any.type) - { - case CLUTTER_BUTTON_PRESS: - case CLUTTER_TOUCH_BEGIN: - return handle_press_event (frame, event); - case CLUTTER_BUTTON_RELEASE: - case CLUTTER_TOUCH_END: - return handle_release_event (frame, event); - case CLUTTER_MOTION: - case CLUTTER_TOUCH_UPDATE: - return handle_motion_event (frame, event); - case CLUTTER_ENTER: - return handle_enter_notify_event (frame, (ClutterCrossingEvent *) event); - case CLUTTER_LEAVE: - return handle_leave_notify_event (frame, (ClutterCrossingEvent *) event); - default: - return FALSE; - } -} - -static GdkRectangle* -control_rect (MetaFrameControl control, - MetaFrameGeometry *fgeom) -{ - GdkRectangle *rect; - - rect = NULL; - switch (control) - { - case META_FRAME_CONTROL_TITLE: - rect = &fgeom->title_rect; - break; - case META_FRAME_CONTROL_DELETE: - rect = &fgeom->close_rect.visible; - break; - case META_FRAME_CONTROL_MENU: - rect = &fgeom->menu_rect.visible; - break; - case META_FRAME_CONTROL_MINIMIZE: - rect = &fgeom->min_rect.visible; - break; - case META_FRAME_CONTROL_MAXIMIZE: - case META_FRAME_CONTROL_UNMAXIMIZE: - rect = &fgeom->max_rect.visible; - 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; - case META_FRAME_CONTROL_CLIENT_AREA: - break; - } - - return rect; -} - -#define TOP_RESIZE_HEIGHT 4 -#define CORNER_SIZE_MULT 2 -static MetaFrameControl -get_control (MetaUIFrame *frame, int root_x, int root_y) -{ - MetaFrameGeometry fgeom; - MetaFrameFlags flags; - MetaFrameType type; - gboolean has_vert, has_horiz; - gboolean has_north_resize; - cairo_rectangle_int_t client; - int x, y; - int win_x, win_y; - - if (meta_window_is_fullscreen (frame->meta_window)) - return META_FRAME_CONTROL_CLIENT_AREA; - - gdk_window_get_position (frame->window, &win_x, &win_y); - x = root_x - win_x; - y = root_y - win_y; - - meta_window_get_client_area_rect (frame->meta_window, &client); - if (META_POINT_IN_RECT (x, y, client)) - return META_FRAME_CONTROL_CLIENT_AREA; - - meta_ui_frame_calc_geometry (frame, &fgeom); - - if (META_POINT_IN_RECT (x, y, fgeom.close_rect.clickable)) - return META_FRAME_CONTROL_DELETE; - - if (META_POINT_IN_RECT (x, y, fgeom.min_rect.clickable)) - return META_FRAME_CONTROL_MINIMIZE; - - if (META_POINT_IN_RECT (x, y, fgeom.menu_rect.clickable)) - return META_FRAME_CONTROL_MENU; - - flags = meta_frame_get_flags (frame->meta_window->frame); - type = meta_window_get_frame_type (frame->meta_window); - - has_north_resize = (type != META_FRAME_TYPE_ATTACHED); - has_vert = (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE) != 0; - has_horiz = (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE) != 0; - - if (flags & META_FRAME_TILED_LEFT || flags & META_FRAME_TILED_RIGHT) - has_vert = has_horiz = FALSE; - - if (META_POINT_IN_RECT (x, y, fgeom.title_rect)) - { - if (has_vert && y <= TOP_RESIZE_HEIGHT && has_north_resize) - return META_FRAME_CONTROL_RESIZE_N; - else - return META_FRAME_CONTROL_TITLE; - } - - if (META_POINT_IN_RECT (x, y, fgeom.max_rect.clickable)) - { - if (flags & META_FRAME_MAXIMIZED) - return META_FRAME_CONTROL_UNMAXIMIZE; - else - return META_FRAME_CONTROL_MAXIMIZE; - } - - /* South resize always has priority over north resize, - * in case of overlap. - */ - - if (y >= (fgeom.height - fgeom.borders.total.bottom * CORNER_SIZE_MULT) && - x >= (fgeom.width - fgeom.borders.total.right * CORNER_SIZE_MULT)) - { - if (has_vert && has_horiz) - return META_FRAME_CONTROL_RESIZE_SE; - else if (has_vert) - return META_FRAME_CONTROL_RESIZE_S; - else if (has_horiz) - return META_FRAME_CONTROL_RESIZE_E; - } - else if (y >= (fgeom.height - fgeom.borders.total.bottom * CORNER_SIZE_MULT) && - x <= fgeom.borders.total.left * CORNER_SIZE_MULT) - { - if (has_vert && has_horiz) - return META_FRAME_CONTROL_RESIZE_SW; - else if (has_vert) - return META_FRAME_CONTROL_RESIZE_S; - else if (has_horiz) - return META_FRAME_CONTROL_RESIZE_W; - } - else if (y < (fgeom.borders.invisible.top * CORNER_SIZE_MULT) && - x <= (fgeom.borders.total.left * CORNER_SIZE_MULT) && has_north_resize) - { - if (has_vert && has_horiz) - return META_FRAME_CONTROL_RESIZE_NW; - else if (has_vert) - return META_FRAME_CONTROL_RESIZE_N; - else if (has_horiz) - return META_FRAME_CONTROL_RESIZE_W; - } - else if (y < (fgeom.borders.invisible.top * CORNER_SIZE_MULT) && - x >= (fgeom.width - fgeom.borders.total.right * CORNER_SIZE_MULT) && has_north_resize) - { - if (has_vert && has_horiz) - return META_FRAME_CONTROL_RESIZE_NE; - else if (has_vert) - return META_FRAME_CONTROL_RESIZE_N; - else if (has_horiz) - return META_FRAME_CONTROL_RESIZE_E; - } - else if (y < (fgeom.borders.invisible.top + TOP_RESIZE_HEIGHT)) - { - if (has_vert && has_north_resize) - return META_FRAME_CONTROL_RESIZE_N; - } - else if (y >= (fgeom.height - fgeom.borders.total.bottom)) - { - if (has_vert) - return META_FRAME_CONTROL_RESIZE_S; - } - else if (x <= fgeom.borders.total.left) - { - if (has_horiz || flags & META_FRAME_TILED_RIGHT) - return META_FRAME_CONTROL_RESIZE_W; - } - else if (x >= (fgeom.width - fgeom.borders.total.right)) - { - if (has_horiz || flags & META_FRAME_TILED_LEFT) - return META_FRAME_CONTROL_RESIZE_E; - } - - if (y >= fgeom.borders.total.top) - return META_FRAME_CONTROL_NONE; - else - return META_FRAME_CONTROL_TITLE; -} diff --git a/src/ui/frames.h b/src/ui/frames.h deleted file mode 100644 index 96b8d845e..000000000 --- a/src/ui/frames.h +++ /dev/null @@ -1,155 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Metacity window frame manager widget */ - -/* - * 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, see . - */ - -#ifndef META_FRAMES_H -#define META_FRAMES_H - -#include -#include - -#include "meta/common.h" -#include "meta/types.h" -#include "ui/theme-private.h" -#include "ui/ui.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_UNMAXIMIZE, - 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, - META_FRAME_CONTROL_CLIENT_AREA -} MetaFrameControl; - -/* This is one widget that manages all the window frames - * as subwindows. - */ - -#define META_TYPE_FRAMES (meta_frames_get_type ()) -#define META_FRAMES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_FRAMES, MetaFrames)) -#define META_FRAMES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_FRAMES, MetaFramesClass)) -#define META_IS_FRAMES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_FRAMES)) -#define META_IS_FRAMES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_FRAMES)) -#define META_FRAMES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_FRAMES, MetaFramesClass)) - -typedef struct _MetaFrames MetaFrames; -typedef struct _MetaFramesClass MetaFramesClass; - -struct _MetaUIFrame -{ - MetaFrames *frames; - MetaWindow *meta_window; - Window xwindow; - GdkWindow *window; - MetaStyleInfo *style_info; - MetaFrameLayout *cache_layout; - PangoLayout *text_layout; - int text_height; - char *title; /* NULL once we have a layout */ - guint maybe_ignore_leave_notify : 1; - - /* FIXME get rid of this, it can just be in the MetaFrames struct */ - MetaFrameControl prelit_control; - MetaButtonState button_state; - int grab_button; - - gboolean is_frozen; -}; - -struct _MetaFrames -{ - GtkWindow parent_instance; - - MetaX11Display *x11_display; - - GHashTable *text_heights; - - GHashTable *frames; - - MetaStyleInfo *normal_style; - GHashTable *style_variants; - - GSettings *interface_settings; - - MetaGrabOp current_grab_op; - MetaUIFrame *grab_frame; - guint grab_button; - gdouble grab_x; - gdouble grab_y; - - ClutterEventSequence *grab_touch; - - float last_click_x; - float last_click_y; - uint32_t last_click_time; - int click_count; -}; - -struct _MetaFramesClass -{ - GtkWindowClass parent_class; - -}; - -GType meta_frames_get_type (void) G_GNUC_CONST; - -MetaFrames * meta_frames_new (MetaX11Display *x11_display); - -MetaUIFrame * meta_frames_manage_window (MetaFrames *frames, - MetaWindow *meta_window, - Window xwindow, - GdkWindow *window); - -void meta_ui_frame_unmanage (MetaUIFrame *frame); - -void meta_ui_frame_set_title (MetaUIFrame *frame, - const char *title); - -void meta_ui_frame_update_style (MetaUIFrame *frame); - -void meta_ui_frame_get_borders (MetaUIFrame *frame, - MetaFrameBorders *borders); - -cairo_region_t * meta_ui_frame_get_bounds (MetaUIFrame *frame); - -void meta_ui_frame_get_mask (MetaUIFrame *frame, - cairo_rectangle_int_t *frame_rect, - cairo_t *cr); - -void meta_ui_frame_move_resize (MetaUIFrame *frame, - int x, int y, int width, int height); - -void meta_ui_frame_queue_draw (MetaUIFrame *frame); - -gboolean meta_ui_frame_handle_event (MetaUIFrame *frame, const ClutterEvent *event); - -#endif diff --git a/src/ui/theme-private.h b/src/ui/theme-private.h deleted file mode 100644 index 269dbe867..000000000 --- a/src/ui/theme-private.h +++ /dev/null @@ -1,281 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Metacity Theme Rendering */ - -/* - * 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, see . - */ - -#ifndef META_THEME_PRIVATE_H -#define META_THEME_PRIVATE_H - -#include - -#include "meta/boxes.h" -#include "meta/common.h" -#include "meta/theme.h" - -/** - * MetaStyleInfo: (skip) - * - */ -typedef struct _MetaStyleInfo MetaStyleInfo; -/** - * MetaFrameLayout: (skip) - * - */ -typedef struct _MetaFrameLayout MetaFrameLayout; -/** - * MetaButtonSpace: (skip) - * - */ -typedef struct _MetaButtonSpace MetaButtonSpace; -/** - * MetaFrameGeometry: (skip) - * - */ -typedef struct _MetaFrameGeometry MetaFrameGeometry; - -/** - * Various parameters used to calculate the geometry of a frame. - **/ -struct _MetaFrameLayout -{ - /** Invisible border required by the theme */ - GtkBorder invisible_border; - /** Border/padding of the entire frame */ - GtkBorder frame_border; - /** Border/padding of the titlebar region */ - GtkBorder titlebar_border; - /** Border/padding of titlebar buttons */ - GtkBorder button_border; - - /** Margin of title */ - GtkBorder title_margin; - /** Margin of titlebar buttons */ - GtkBorder button_margin; - - /** Min size of titlebar region */ - GtkRequisition titlebar_min_size; - /** Min size of titlebar buttons */ - GtkRequisition button_min_size; - - /** Size of images in buttons */ - guint icon_size; - - /** Space between titlebar elements */ - guint titlebar_spacing; - - /** scale factor for title text */ - double title_scale; - - /** Whether title text will be displayed */ - guint has_title : 1; - - /** Whether we should hide the buttons */ - guint hide_buttons : 1; - - /** Radius of the top left-hand corner; 0 if not rounded */ - guint top_left_corner_rounded_radius; - /** Radius of the top right-hand corner; 0 if not rounded */ - guint top_right_corner_rounded_radius; - /** Radius of the bottom left-hand corner; 0 if not rounded */ - guint bottom_left_corner_rounded_radius; - /** Radius of the bottom right-hand corner; 0 if not rounded */ - guint bottom_right_corner_rounded_radius; -}; - -/** - * The computed size of a button (really just a way of tying its - * visible and clickable areas together). - * The reason for two different rectangles here is Fitts' law & maximized - * windows; see bug #97703 for more details. - */ -struct _MetaButtonSpace -{ - /** The screen area where the button's image is drawn */ - GdkRectangle visible; - /** The screen area where the button can be activated by clicking */ - GdkRectangle clickable; -}; - -/** - * Calculated actual geometry of the frame - */ -struct _MetaFrameGeometry -{ - MetaFrameBorders borders; - - int width; - int height; - - GdkRectangle title_rect; - - GtkBorder content_border; - - /* used for a memset hack */ -#define ADDRESS_OF_BUTTON_RECTS(fgeom) (((char*)(fgeom)) + G_STRUCT_OFFSET (MetaFrameGeometry, close_rect)) -#define LENGTH_OF_BUTTON_RECTS (G_STRUCT_OFFSET (MetaFrameGeometry, menu_rect) + sizeof (MetaButtonSpace) - G_STRUCT_OFFSET (MetaFrameGeometry, close_rect)) - - /* The button rects (if changed adjust memset hack) */ - MetaButtonSpace close_rect; - MetaButtonSpace max_rect; - MetaButtonSpace min_rect; - MetaButtonSpace menu_rect; - /* End of button rects (if changed adjust memset hack) */ - - /* Saved button layout */ - MetaButtonLayout button_layout; - int n_left_buttons; - int n_right_buttons; - - /* Round corners */ - guint top_left_corner_rounded_radius; - guint top_right_corner_rounded_radius; - guint bottom_left_corner_rounded_radius; - guint bottom_right_corner_rounded_radius; -}; - -typedef enum -{ - META_BUTTON_STATE_NORMAL, - META_BUTTON_STATE_PRESSED, - META_BUTTON_STATE_PRELIGHT, - META_BUTTON_STATE_LAST -} MetaButtonState; - -typedef enum -{ - META_BUTTON_TYPE_CLOSE, - META_BUTTON_TYPE_MAXIMIZE, - META_BUTTON_TYPE_MINIMIZE, - META_BUTTON_TYPE_MENU, - META_BUTTON_TYPE_LAST -} MetaButtonType; - -typedef enum -{ - META_STYLE_ELEMENT_WINDOW, - META_STYLE_ELEMENT_FRAME, - META_STYLE_ELEMENT_TITLEBAR, - META_STYLE_ELEMENT_TITLE, - META_STYLE_ELEMENT_BUTTON, - META_STYLE_ELEMENT_IMAGE, - META_STYLE_ELEMENT_LAST -} MetaStyleElement; - -struct _MetaStyleInfo -{ - int refcount; - - GtkStyleContext *styles[META_STYLE_ELEMENT_LAST]; -}; - -/* Kinds of frame... - * - * normal -> focused / unfocused - * max -> focused / unfocused - * shaded -> focused / unfocused - * max/shaded -> focused / unfocused - * - * so 4 states with 2 sub-states each, meaning 8 total - * - * 8 window states times 7 or 8 window types. Except some - * window types never get a frame so that narrows it down a bit. - * - */ -typedef enum -{ - META_FRAME_STATE_NORMAL, - META_FRAME_STATE_MAXIMIZED, - META_FRAME_STATE_TILED_LEFT, - META_FRAME_STATE_TILED_RIGHT, - META_FRAME_STATE_SHADED, - META_FRAME_STATE_MAXIMIZED_AND_SHADED, - META_FRAME_STATE_TILED_LEFT_AND_SHADED, - META_FRAME_STATE_TILED_RIGHT_AND_SHADED, - META_FRAME_STATE_LAST -} MetaFrameState; - -typedef enum -{ - META_FRAME_FOCUS_NO, - META_FRAME_FOCUS_YES, - META_FRAME_FOCUS_LAST -} MetaFrameFocus; - -/** - * A theme. This is a singleton class which groups all settings from a theme - * together. - */ -struct _MetaTheme -{ - MetaFrameLayout *layouts[META_FRAME_TYPE_LAST]; -}; - -void meta_frame_layout_apply_scale (const MetaFrameLayout *layout, - PangoFontDescription *font_desc); - -MetaFrameLayout* meta_theme_get_frame_layout (MetaTheme *theme, - MetaFrameType type); - -MetaStyleInfo * meta_theme_create_style_info (GdkScreen *screen, - const gchar *variant); -MetaStyleInfo * meta_style_info_ref (MetaStyleInfo *style); -void meta_style_info_unref (MetaStyleInfo *style_info); - -void meta_style_info_set_flags (MetaStyleInfo *style_info, - MetaFrameFlags flags); - -PangoFontDescription * meta_style_info_create_font_desc (MetaStyleInfo *style_info); - -void meta_theme_draw_frame (MetaTheme *theme, - MetaStyleInfo *style_info, - cairo_t *cr, - MetaFrameType type, - MetaFrameFlags flags, - int client_width, - int client_height, - PangoLayout *title_layout, - int text_height, - const MetaButtonLayout *button_layout, - MetaButtonState button_states[META_BUTTON_TYPE_LAST], - cairo_surface_t *mini_icon); - -void meta_theme_get_frame_borders (MetaTheme *theme, - MetaStyleInfo *style_info, - MetaFrameType type, - int text_height, - MetaFrameFlags flags, - MetaFrameBorders *borders); - -void meta_theme_calc_geometry (MetaTheme *theme, - MetaStyleInfo *style_info, - MetaFrameType type, - int text_height, - MetaFrameFlags flags, - int client_width, - int client_height, - const MetaButtonLayout *button_layout, - MetaFrameGeometry *fgeom); - -/* random stuff */ - -int meta_pango_font_desc_get_text_height (const PangoFontDescription *font_desc, - PangoContext *context); -int meta_theme_get_window_scaling_factor (void); - -#endif /* META_THEME_PRIVATE_H */ diff --git a/src/ui/theme.c b/src/ui/theme.c deleted file mode 100644 index 9e488c073..000000000 --- a/src/ui/theme.c +++ /dev/null @@ -1,1358 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * 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, see . - */ - -#include "config.h" - -#include "ui/theme-private.h" - -#include -#include -#include -#include -#include - -#include "core/util-private.h" -#include "meta/prefs.h" -#include "ui/frames.h" - -static void scale_border (GtkBorder *border, double factor); - -static MetaFrameLayout * -meta_frame_layout_new (void) -{ - MetaFrameLayout *layout; - - layout = g_new0 (MetaFrameLayout, 1); - - /* Spacing as hardcoded in GTK+: - * https://git.gnome.org/browse/gtk+/tree/gtk/gtkheaderbar.c?h=gtk-3-14#n53 - */ - layout->titlebar_spacing = 6; - layout->has_title = TRUE; - layout->title_scale = PANGO_SCALE_MEDIUM; - layout->icon_size = META_MINI_ICON_WIDTH; - - return layout; -} - -static void -meta_frame_layout_free (MetaFrameLayout *layout) -{ - g_return_if_fail (layout != NULL); - - g_free (layout); -} - -static void -meta_frame_layout_get_borders (const MetaFrameLayout *layout, - int text_height, - MetaFrameFlags flags, - MetaFrameType type, - MetaFrameBorders *borders) -{ - int buttons_height, content_height, draggable_borders; - int scale = meta_theme_get_window_scaling_factor (); - - meta_frame_borders_clear (borders); - - /* For a full-screen window, we don't have any borders, visible or not. */ - if (flags & META_FRAME_FULLSCREEN) - return; - - g_return_if_fail (layout != NULL); - - if (!layout->has_title) - text_height = 0; - else - text_height = layout->title_margin.top + text_height + layout->title_margin.bottom; - - buttons_height = MAX ((int)layout->icon_size, layout->button_min_size.height) + - layout->button_margin.top + layout->button_border.top + - layout->button_margin.bottom + layout->button_border.bottom; - content_height = MAX (buttons_height, text_height); - content_height = MAX (content_height, layout->titlebar_min_size.height) + - layout->titlebar_border.top + layout->titlebar_border.bottom; - - borders->visible.top = layout->frame_border.top + content_height; - borders->visible.left = layout->frame_border.left; - borders->visible.right = layout->frame_border.right; - borders->visible.bottom = layout->frame_border.bottom; - - borders->invisible = layout->invisible_border; - - draggable_borders = meta_prefs_get_draggable_border_width (); - - if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE) - { - borders->invisible.left = MAX (borders->invisible.left, - draggable_borders - borders->visible.left); - borders->invisible.right = MAX (borders->invisible.right, - draggable_borders - borders->visible.right); - } - - if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE) - { - borders->invisible.bottom = MAX (borders->invisible.bottom, - draggable_borders - borders->visible.bottom); - - /* borders.visible.top is the height of the *title bar*. We can't do the same - * algorithm here, titlebars are expectedly much bigger. Just subtract a couple - * pixels to get a proper feel. */ - if (type != META_FRAME_TYPE_ATTACHED) - borders->invisible.top = MAX (borders->invisible.top, draggable_borders - 2); - } - - borders->total.left = borders->invisible.left + borders->visible.left; - borders->total.right = borders->invisible.right + borders->visible.right; - borders->total.bottom = borders->invisible.bottom + borders->visible.bottom; - borders->total.top = borders->invisible.top + borders->visible.top; - - /* Scale geometry for HiDPI, see comment in meta_frame_layout_draw_with_style() */ - scale_border (&borders->visible, scale); - scale_border (&borders->invisible, scale); - scale_border (&borders->total, scale); -} - -int -meta_theme_get_window_scaling_factor (void) -{ - GdkScreen *screen; - GValue value = G_VALUE_INIT; - - g_value_init (&value, G_TYPE_INT); - - screen = gdk_screen_get_default (); - if (gdk_screen_get_setting (screen, "gdk-window-scaling-factor", &value)) - return g_value_get_int (&value); - else - return 1; -} - -void -meta_frame_layout_apply_scale (const MetaFrameLayout *layout, - PangoFontDescription *font_desc) -{ - int size = pango_font_description_get_size (font_desc); - double scale = layout->title_scale / meta_theme_get_window_scaling_factor (); - pango_font_description_set_size (font_desc, MAX (size * scale, 1)); -} - -static MetaButtonSpace* -rect_for_function (MetaFrameGeometry *fgeom, - MetaFrameFlags flags, - MetaButtonFunction function, - MetaTheme *theme) -{ - switch (function) - { - case META_BUTTON_FUNCTION_MENU: - if (flags & META_FRAME_ALLOWS_MENU) - return &fgeom->menu_rect; - else - return NULL; - case META_BUTTON_FUNCTION_MINIMIZE: - if (flags & META_FRAME_ALLOWS_MINIMIZE) - return &fgeom->min_rect; - else - return NULL; - case META_BUTTON_FUNCTION_MAXIMIZE: - if (flags & META_FRAME_ALLOWS_MAXIMIZE) - return &fgeom->max_rect; - else - return NULL; - case META_BUTTON_FUNCTION_CLOSE: - if (flags & META_FRAME_ALLOWS_DELETE) - return &fgeom->close_rect; - else - return NULL; - - case META_BUTTON_FUNCTION_LAST: - return NULL; - } - - return NULL; -} - -static gboolean -strip_button (MetaButtonSpace *func_rects[MAX_BUTTONS_PER_CORNER], - int *n_rects, - MetaButtonSpace *to_strip) -{ - int i; - - i = 0; - while (i < *n_rects) - { - if (func_rects[i] == to_strip) - { - *n_rects -= 1; - - /* shift the other rects back in the array */ - while (i < *n_rects) - { - func_rects[i] = func_rects[i+1]; - - ++i; - } - - func_rects[i] = NULL; - - return TRUE; - } - - ++i; - } - - return FALSE; /* did not strip anything */ -} - -static void -get_padding_and_border (GtkStyleContext *style, - GtkBorder *border) -{ - GtkBorder tmp; - GtkStateFlags state = gtk_style_context_get_state (style); - - gtk_style_context_get_border (style, state, border); - gtk_style_context_get_padding (style, state, &tmp); - - border->left += tmp.left; - border->top += tmp.top; - border->right += tmp.right; - border->bottom += tmp.bottom; -} - -static void -get_min_size (GtkStyleContext *style, - GtkRequisition *requisition) -{ - gtk_style_context_get (style, gtk_style_context_get_state (style), - "min-width", &requisition->width, - "min-height", &requisition->height, - NULL); -} - -static void -scale_border (GtkBorder *border, - double factor) -{ - border->left *= factor; - border->right *= factor; - border->top *= factor; - border->bottom *= factor; -} - -static void -meta_frame_layout_sync_with_style (MetaFrameLayout *layout, - MetaStyleInfo *style_info, - MetaFrameFlags flags) -{ - GtkStyleContext *style; - GtkBorder border; - GtkRequisition requisition; - GdkRectangle clip_rect; - int border_radius, max_radius; - - meta_style_info_set_flags (style_info, flags); - - style = style_info->styles[META_STYLE_ELEMENT_FRAME]; - get_padding_and_border (style, &layout->frame_border); - scale_border (&layout->frame_border, layout->title_scale); - - gtk_render_background_get_clip (style, 0, 0, 0, 0, &clip_rect); - layout->invisible_border.left = -clip_rect.x; - layout->invisible_border.right = clip_rect.width + clip_rect.x; - layout->invisible_border.top = -clip_rect.y; - layout->invisible_border.bottom = clip_rect.height + clip_rect.y; - - if (layout->hide_buttons) - layout->icon_size = 0; - - if (!layout->has_title && layout->hide_buttons) - return; /* border-only - be done */ - - style = style_info->styles[META_STYLE_ELEMENT_TITLEBAR]; - gtk_style_context_get (style, gtk_style_context_get_state (style), - "border-radius", &border_radius, - NULL); - /* GTK+ currently does not allow us to look up radii of individual - * corners; however we don't clip the client area, so with the - * current trend of using small/no visible frame borders, most - * themes should work fine with this. - */ - layout->top_left_corner_rounded_radius = border_radius; - layout->top_right_corner_rounded_radius = border_radius; - max_radius = MIN (layout->frame_border.bottom, layout->frame_border.left); - layout->bottom_left_corner_rounded_radius = MAX (border_radius, max_radius); - max_radius = MIN (layout->frame_border.bottom, layout->frame_border.right); - layout->bottom_right_corner_rounded_radius = MAX (border_radius, max_radius); - - get_min_size (style, &layout->titlebar_min_size); - get_padding_and_border (style, &layout->titlebar_border); - scale_border (&layout->titlebar_border, layout->title_scale); - - style = style_info->styles[META_STYLE_ELEMENT_TITLE]; - gtk_style_context_get_margin (style, gtk_style_context_get_state (style), - &layout->title_margin); - scale_border (&layout->title_margin, layout->title_scale); - - style = style_info->styles[META_STYLE_ELEMENT_BUTTON]; - get_min_size (style, &layout->button_min_size); - get_padding_and_border (style, &layout->button_border); - scale_border (&layout->button_border, layout->title_scale); - gtk_style_context_get_margin (style, gtk_style_context_get_state (style), - &layout->button_margin); - scale_border (&layout->button_margin, layout->title_scale); - - style = style_info->styles[META_STYLE_ELEMENT_IMAGE]; - get_min_size (style, &requisition); - get_padding_and_border (style, &border); - scale_border (&border, layout->title_scale); - - layout->button_border.left += border.left; - layout->button_border.right += border.right; - layout->button_border.top += border.top; - layout->button_border.bottom += border.bottom; - - gtk_style_context_get_margin (style, gtk_style_context_get_state (style), - &border); - layout->button_border.left += border.left; - layout->button_border.right += border.right; - layout->button_border.top += border.top; - layout->button_border.bottom += border.bottom; - - layout->button_min_size.width = MAX(layout->button_min_size.width, - requisition.width); - layout->button_min_size.height = MAX(layout->button_min_size.height, - requisition.height); -} - -static void -meta_frame_layout_calc_geometry (MetaFrameLayout *layout, - MetaStyleInfo *style_info, - int text_height, - MetaFrameFlags flags, - int client_width, - int client_height, - const MetaButtonLayout *button_layout, - MetaFrameType type, - MetaFrameGeometry *fgeom, - MetaTheme *theme) -{ - int i, n_left, n_right, n_left_spacers, n_right_spacers; - int x; - int button_y; - int title_right_edge; - int width, height; - int content_width, content_height; - int button_width, button_height; - int min_size_for_rounding; - int scale = meta_theme_get_window_scaling_factor (); - - /* the left/right rects in order; the max # of rects - * is the number of button functions - */ - MetaButtonSpace *left_func_rects[MAX_BUTTONS_PER_CORNER]; - MetaButtonSpace *right_func_rects[MAX_BUTTONS_PER_CORNER]; - gboolean left_buttons_has_spacer[MAX_BUTTONS_PER_CORNER]; - gboolean right_buttons_has_spacer[MAX_BUTTONS_PER_CORNER]; - - MetaFrameBorders borders; - - meta_frame_layout_sync_with_style (layout, style_info, flags); - - meta_frame_layout_get_borders (layout, text_height, - flags, type, - &borders); - - fgeom->borders = borders; - - /* Scale geometry for HiDPI, see comment in meta_frame_layout_draw_with_style() */ - fgeom->content_border = layout->frame_border; - fgeom->content_border.left += layout->titlebar_border.left * scale; - fgeom->content_border.right += layout->titlebar_border.right * scale; - fgeom->content_border.top += layout->titlebar_border.top * scale; - fgeom->content_border.bottom += layout->titlebar_border.bottom * scale; - - width = client_width + borders.total.left + borders.total.right; - - height = borders.total.top + borders.total.bottom; - if (!(flags & META_FRAME_SHADED)) - height += client_height; - - fgeom->width = width; - fgeom->height = height; - - content_width = width - - (fgeom->content_border.left + borders.invisible.left) - - (fgeom->content_border.right + borders.invisible.right); - content_height = borders.visible.top - fgeom->content_border.top - fgeom->content_border.bottom; - - button_width = MAX ((int)layout->icon_size, layout->button_min_size.width) + - layout->button_border.left + layout->button_border.right; - button_height = MAX ((int)layout->icon_size, layout->button_min_size.height) + - layout->button_border.top + layout->button_border.bottom; - button_width *= scale; - button_height *= scale; - - /* FIXME all this code sort of pretends that duplicate buttons - * with the same function are allowed, but that breaks the - * code in frames.c, so isn't really allowed right now. - * Would need left_close_rect, right_close_rect, etc. - */ - - /* Init all button rects to 0, lame hack */ - memset (ADDRESS_OF_BUTTON_RECTS (fgeom), '\0', - LENGTH_OF_BUTTON_RECTS); - - n_left = 0; - n_right = 0; - n_left_spacers = 0; - n_right_spacers = 0; - - if (!layout->hide_buttons) - { - /* Try to fill in rects */ - for (i = 0; i < MAX_BUTTONS_PER_CORNER && button_layout->left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++) - { - left_func_rects[n_left] = rect_for_function (fgeom, flags, - button_layout->left_buttons[i], - theme); - if (left_func_rects[n_left] != NULL) - { - left_buttons_has_spacer[n_left] = button_layout->left_buttons_has_spacer[i]; - if (button_layout->left_buttons_has_spacer[i]) - ++n_left_spacers; - - ++n_left; - } - } - - for (i = 0; i < MAX_BUTTONS_PER_CORNER && button_layout->right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++) - { - right_func_rects[n_right] = rect_for_function (fgeom, flags, - button_layout->right_buttons[i], - theme); - if (right_func_rects[n_right] != NULL) - { - right_buttons_has_spacer[n_right] = button_layout->right_buttons_has_spacer[i]; - if (button_layout->right_buttons_has_spacer[i]) - ++n_right_spacers; - - ++n_right; - } - } - } - - /* Be sure buttons fit */ - while (n_left > 0 || n_right > 0) - { - int space_used_by_buttons; - - space_used_by_buttons = 0; - - space_used_by_buttons += layout->button_margin.left * scale * n_left; - space_used_by_buttons += button_width * n_left; - space_used_by_buttons += layout->button_margin.right * scale * n_left; - space_used_by_buttons += (button_width * 0.75) * n_left_spacers; - space_used_by_buttons += layout->titlebar_spacing * scale * MAX (n_left - 1, 0); - - space_used_by_buttons += layout->button_margin.left * scale * n_right; - space_used_by_buttons += button_width * n_right; - space_used_by_buttons += layout->button_margin.right * scale * n_right; - space_used_by_buttons += (button_width * 0.75) * n_right_spacers; - space_used_by_buttons += layout->titlebar_spacing * scale * MAX (n_right - 1, 0); - - if (space_used_by_buttons <= content_width) - break; /* Everything fits, bail out */ - - /* First try to remove separators */ - if (n_left_spacers > 0) - { - left_buttons_has_spacer[--n_left_spacers] = FALSE; - continue; - } - else if (n_right_spacers > 0) - { - right_buttons_has_spacer[--n_right_spacers] = FALSE; - continue; - } - - /* Otherwise we need to shave out a button. Shave - * min, max, close, then menu (menu is most useful); - * prefer the default button locations. - */ - if (strip_button (left_func_rects, &n_left, &fgeom->min_rect)) - continue; - else if (strip_button (right_func_rects, &n_right, &fgeom->min_rect)) - continue; - else if (strip_button (left_func_rects, &n_left, &fgeom->max_rect)) - continue; - else if (strip_button (right_func_rects, &n_right, &fgeom->max_rect)) - continue; - else if (strip_button (left_func_rects, &n_left, &fgeom->close_rect)) - continue; - else if (strip_button (right_func_rects, &n_right, &fgeom->close_rect)) - continue; - else if (strip_button (right_func_rects, &n_right, &fgeom->menu_rect)) - continue; - else if (strip_button (left_func_rects, &n_left, &fgeom->menu_rect)) - continue; - else - { - meta_bug ("Could not find a button to strip. n_left = %d n_right = %d", - n_left, n_right); - } - } - - /* Save the button layout */ - fgeom->button_layout = *button_layout; - fgeom->n_left_buttons = n_left; - fgeom->n_right_buttons = n_right; - - /* center buttons vertically */ - button_y = fgeom->content_border.top + borders.invisible.top + - (content_height - button_height) / 2; - - /* right edge of farthest-right button */ - x = width - fgeom->content_border.right - borders.invisible.right; - - i = n_right - 1; - while (i >= 0) - { - MetaButtonSpace *rect; - - if (x < 0) /* if we go negative, leave the buttons we don't get to as 0-width */ - break; - - x -= layout->button_margin.right * scale; - - rect = right_func_rects[i]; - rect->visible.x = x - button_width; - if (right_buttons_has_spacer[i]) - rect->visible.x -= (button_width * 0.75); - - rect->visible.y = button_y; - rect->visible.width = button_width; - rect->visible.height = button_height; - - if (flags & META_FRAME_MAXIMIZED || - flags & META_FRAME_TILED_LEFT || - flags & META_FRAME_TILED_RIGHT) - { - rect->clickable.x = rect->visible.x; - rect->clickable.y = 0; - rect->clickable.width = rect->visible.width; - rect->clickable.height = button_height + button_y; - - if (i == n_right - 1) - rect->clickable.width += fgeom->content_border.right; - - } - else - memmove (&(rect->clickable), &(rect->visible), sizeof (rect->clickable)); - - x = rect->visible.x - layout->button_margin.left * scale; - - if (i > 0) - x -= layout->titlebar_spacing * scale; - - --i; - } - - /* save right edge of titlebar for later use */ - title_right_edge = x; - - /* Now x changes to be position from the left and we go through - * the left-side buttons - */ - x = fgeom->content_border.left + borders.invisible.left; - for (i = 0; i < n_left; i++) - { - MetaButtonSpace *rect; - - x += layout->button_margin.left * scale; - - rect = left_func_rects[i]; - - rect->visible.x = x; - rect->visible.y = button_y; - rect->visible.width = button_width; - rect->visible.height = button_height; - - if (flags & META_FRAME_MAXIMIZED) - { - if (i==0) - { - rect->clickable.x = 0; - rect->clickable.width = button_width + x; - } - else - { - rect->clickable.x = rect->visible.x; - rect->clickable.width = button_width; - } - - rect->clickable.y = 0; - rect->clickable.height = button_height + button_y; - } - else - memmove (&(rect->clickable), &(rect->visible), sizeof (rect->clickable)); - - x = rect->visible.x + rect->visible.width + layout->button_margin.right * scale; - if (i < n_left - 1) - x += layout->titlebar_spacing * scale; - if (left_buttons_has_spacer[i]) - x += (button_width * 0.75); - } - - /* Center vertically in the available content area */ - fgeom->title_rect.x = x; - fgeom->title_rect.y = fgeom->content_border.top + borders.invisible.top + - (content_height - text_height) / 2; - fgeom->title_rect.width = title_right_edge - fgeom->title_rect.x; - fgeom->title_rect.height = text_height; - - /* Nuke title if it won't fit */ - if (fgeom->title_rect.width < 0 || - fgeom->title_rect.height < 0) - { - fgeom->title_rect.width = 0; - fgeom->title_rect.height = 0; - } - - if (flags & META_FRAME_SHADED) - min_size_for_rounding = 0; - else - min_size_for_rounding = 5 * scale; - - fgeom->top_left_corner_rounded_radius = 0; - fgeom->top_right_corner_rounded_radius = 0; - fgeom->bottom_left_corner_rounded_radius = 0; - fgeom->bottom_right_corner_rounded_radius = 0; - - if (borders.visible.top + borders.visible.left >= min_size_for_rounding) - fgeom->top_left_corner_rounded_radius = layout->top_left_corner_rounded_radius * scale; - if (borders.visible.top + borders.visible.right >= min_size_for_rounding) - fgeom->top_right_corner_rounded_radius = layout->top_right_corner_rounded_radius * scale; - - if (borders.visible.bottom + borders.visible.left >= min_size_for_rounding) - fgeom->bottom_left_corner_rounded_radius = layout->bottom_left_corner_rounded_radius * scale; - if (borders.visible.bottom + borders.visible.right >= min_size_for_rounding) - fgeom->bottom_right_corner_rounded_radius = layout->bottom_right_corner_rounded_radius * scale; -} - -static void -get_button_rect (MetaButtonType type, - const MetaFrameGeometry *fgeom, - GdkRectangle *rect) -{ - switch (type) - { - case META_BUTTON_TYPE_CLOSE: - *rect = fgeom->close_rect.visible; - break; - - case META_BUTTON_TYPE_MAXIMIZE: - *rect = fgeom->max_rect.visible; - break; - - case META_BUTTON_TYPE_MINIMIZE: - *rect = fgeom->min_rect.visible; - break; - - case META_BUTTON_TYPE_MENU: - *rect = fgeom->menu_rect.visible; - break; - - default: - case META_BUTTON_TYPE_LAST: - g_assert_not_reached (); - break; - } -} - -static const char * -get_class_from_button_type (MetaButtonType type) -{ - switch (type) - { - case META_BUTTON_TYPE_CLOSE: - return "close"; - case META_BUTTON_TYPE_MAXIMIZE: - return "maximize"; - case META_BUTTON_TYPE_MINIMIZE: - return "minimize"; - default: - return NULL; - } -} - -static void -meta_frame_layout_draw_with_style (MetaFrameLayout *layout, - MetaStyleInfo *style_info, - cairo_t *cr, - const MetaFrameGeometry *fgeom, - PangoLayout *title_layout, - MetaFrameFlags flags, - MetaButtonState button_states[META_BUTTON_TYPE_LAST], - cairo_surface_t *mini_icon) -{ - GtkStyleContext *style; - GtkStateFlags state; - MetaButtonType button_type; - GdkRectangle visible_rect; - GdkRectangle titlebar_rect; - GdkRectangle button_rect; - const MetaFrameBorders *borders; - cairo_surface_t *frame_surface; - double xscale, yscale; - int scale; - - /* We opt out of GTK+/Clutter's HiDPI handling, so we have to do the scaling - * ourselves; the nitty-gritty is a bit confusing, so here is an overview: - * - the values in MetaFrameLayout are always as they appear in the theme, - * i.e. unscaled - * - calculated values (borders, MetaFrameGeometry) include the scale - as - * the geometry is comprised of scaled decorations and the client size - * which we must not scale, we don't have another option - * - for drawing, we scale the canvas to have GTK+ render elements (borders, - * radii, ...) at the correct scale - as a result, we have to "unscale" - * the geometry again to not apply the scaling twice - * - As per commit e36b629c GTK expects the device scale to be set and match - * the final scaling or the surface caching won't take this in account - * breaking -gtk-scaled items. - */ - scale = meta_theme_get_window_scaling_factor (); - frame_surface = cairo_get_target (cr); - cairo_surface_get_device_scale (frame_surface, &xscale, &yscale); - cairo_surface_set_device_scale (frame_surface, scale, scale); - - borders = &fgeom->borders; - - visible_rect.x = borders->invisible.left / scale; - visible_rect.y = borders->invisible.top / scale; - visible_rect.width = (fgeom->width - borders->invisible.left - borders->invisible.right) / scale; - visible_rect.height = (fgeom->height - borders->invisible.top - borders->invisible.bottom) / scale; - - meta_style_info_set_flags (style_info, flags); - - style = style_info->styles[META_STYLE_ELEMENT_FRAME]; - gtk_render_background (style, cr, - visible_rect.x, visible_rect.y, - visible_rect.width, visible_rect.height); - gtk_render_frame (style, cr, - visible_rect.x, visible_rect.y, - visible_rect.width, visible_rect.height); - - titlebar_rect.x = visible_rect.x; - titlebar_rect.y = visible_rect.y; - titlebar_rect.width = visible_rect.width; - titlebar_rect.height = borders->visible.top / scale; - - style = style_info->styles[META_STYLE_ELEMENT_TITLEBAR]; - gtk_render_background (style, cr, - titlebar_rect.x, titlebar_rect.y, - titlebar_rect.width, titlebar_rect.height); - gtk_render_frame (style, cr, - titlebar_rect.x, titlebar_rect.y, - titlebar_rect.width, titlebar_rect.height); - - if (layout->has_title && title_layout) - { - PangoRectangle logical; - int text_width, x, y; - - pango_layout_set_width (title_layout, -1); - pango_layout_get_pixel_extents (title_layout, NULL, &logical); - - text_width = MIN(fgeom->title_rect.width / scale, logical.width); - - if (text_width < logical.width) - pango_layout_set_width (title_layout, PANGO_SCALE * text_width); - - /* Center within the frame if possible */ - x = titlebar_rect.x + (titlebar_rect.width - text_width) / 2; - y = titlebar_rect.y + (titlebar_rect.height - logical.height) / 2; - - if (x < fgeom->title_rect.x / scale) - x = fgeom->title_rect.x / scale; - else if (x + text_width > (fgeom->title_rect.x + fgeom->title_rect.width) / scale) - x = (fgeom->title_rect.x + fgeom->title_rect.width) / scale - text_width; - - style = style_info->styles[META_STYLE_ELEMENT_TITLE]; - gtk_render_layout (style, cr, x, y, title_layout); - } - - style = style_info->styles[META_STYLE_ELEMENT_BUTTON]; - state = gtk_style_context_get_state (style); - for (button_type = META_BUTTON_TYPE_CLOSE; button_type < META_BUTTON_TYPE_LAST; button_type++) - { - const char *button_class = get_class_from_button_type (button_type); - if (button_class) - gtk_style_context_add_class (style, button_class); - - get_button_rect (button_type, fgeom, &button_rect); - - button_rect.x /= scale; - button_rect.y /= scale; - button_rect.width /= scale; - button_rect.height /= scale; - - if (button_states[button_type] == META_BUTTON_STATE_PRELIGHT) - gtk_style_context_set_state (style, state | GTK_STATE_PRELIGHT); - else if (button_states[button_type] == META_BUTTON_STATE_PRESSED) - gtk_style_context_set_state (style, state | GTK_STATE_ACTIVE); - else - gtk_style_context_set_state (style, state); - - cairo_save (cr); - - if (button_rect.width > 0 && button_rect.height > 0) - { - cairo_surface_t *surface = NULL; - const char *icon_name = NULL; - - gtk_render_background (style, cr, - button_rect.x, button_rect.y, - button_rect.width, button_rect.height); - gtk_render_frame (style, cr, - button_rect.x, button_rect.y, - button_rect.width, button_rect.height); - - switch (button_type) - { - case META_BUTTON_TYPE_CLOSE: - icon_name = "window-close-symbolic"; - break; - case META_BUTTON_TYPE_MAXIMIZE: - if (flags & META_FRAME_MAXIMIZED) - icon_name = "window-restore-symbolic"; - else - icon_name = "window-maximize-symbolic"; - break; - case META_BUTTON_TYPE_MINIMIZE: - icon_name = "window-minimize-symbolic"; - break; - case META_BUTTON_TYPE_MENU: - icon_name = "open-menu-symbolic"; - break; - default: - icon_name = NULL; - break; - } - - if (icon_name) - { - GtkIconTheme *theme = gtk_icon_theme_get_default (); - g_autoptr (GtkIconInfo) info = NULL; - g_autoptr (GdkPixbuf) pixbuf = NULL; - - info = gtk_icon_theme_lookup_icon_for_scale (theme, icon_name, - layout->icon_size, scale, 0); - pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL); - surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL); - } - - if (surface) - { - float width, height; - int x, y; - - width = cairo_image_surface_get_width (surface) / scale; - height = cairo_image_surface_get_height (surface) / scale; - x = button_rect.x + (button_rect.width - layout->icon_size) / 2; - y = button_rect.y + (button_rect.height - layout->icon_size) / 2; - - cairo_translate (cr, x, y); - cairo_scale (cr, - layout->icon_size / width, - layout->icon_size / height); - cairo_set_source_surface (cr, surface, 0, 0); - cairo_paint (cr); - - cairo_surface_destroy (surface); - } - } - cairo_restore (cr); - if (button_class) - gtk_style_context_remove_class (style, button_class); - gtk_style_context_set_state (style, state); - } - - cairo_surface_set_device_scale (frame_surface, xscale, yscale); -} - -/** - * meta_theme_get_default: (skip) - * - */ -MetaTheme* -meta_theme_get_default (void) -{ - static MetaTheme *theme = NULL; - int frame_type; - - if (theme) - return theme; - - theme = meta_theme_new (); - - for (frame_type = 0; frame_type < META_FRAME_TYPE_LAST; frame_type++) - { - MetaFrameLayout *layout = meta_frame_layout_new (); - - switch (frame_type) - { - case META_FRAME_TYPE_NORMAL: - case META_FRAME_TYPE_DIALOG: - case META_FRAME_TYPE_MODAL_DIALOG: - case META_FRAME_TYPE_ATTACHED: - break; - case META_FRAME_TYPE_MENU: - case META_FRAME_TYPE_UTILITY: - layout->title_scale = PANGO_SCALE_SMALL; - break; - case META_FRAME_TYPE_BORDER: - layout->has_title = FALSE; - layout->hide_buttons = TRUE; - break; - default: - g_assert_not_reached (); - } - - theme->layouts[frame_type] = layout; - } - return theme; -} - -/** - * meta_theme_new: (skip) - * - */ -MetaTheme* -meta_theme_new (void) -{ - return g_new0 (MetaTheme, 1); -} - - -void -meta_theme_free (MetaTheme *theme) -{ - int i; - - g_return_if_fail (theme != NULL); - - for (i = 0; i < META_FRAME_TYPE_LAST; i++) - if (theme->layouts[i]) - meta_frame_layout_free (theme->layouts[i]); - - g_free (theme); -} - -MetaFrameLayout* -meta_theme_get_frame_layout (MetaTheme *theme, - MetaFrameType type) -{ - g_return_val_if_fail (type < META_FRAME_TYPE_LAST, NULL); - - return theme->layouts[type]; -} - -static GtkStyleContext * -create_style_context (GType widget_type, - GtkStyleContext *parent_style, - GtkCssProvider *provider, - const char *object_name, - const char *first_class, - ...) -{ - GtkStyleContext *style; - GtkStateFlags state; - GtkWidgetPath *path; - const char *name; - va_list ap; - - style = gtk_style_context_new (); - gtk_style_context_set_scale (style, meta_theme_get_window_scaling_factor ()); - gtk_style_context_set_parent (style, parent_style); - - if (parent_style) - path = gtk_widget_path_copy (gtk_style_context_get_path (parent_style)); - else - path = gtk_widget_path_new (); - - gtk_widget_path_append_type (path, widget_type); - - if (object_name) - gtk_widget_path_iter_set_object_name (path, -1, object_name); - - state = gtk_style_context_get_state (style); - if (meta_get_locale_direction() == META_LOCALE_DIRECTION_RTL) - { - state |= GTK_STATE_FLAG_DIR_RTL; - state &= ~GTK_STATE_FLAG_DIR_LTR; - } - else - { - state |= GTK_STATE_FLAG_DIR_LTR; - state &= ~GTK_STATE_FLAG_DIR_RTL; - } - gtk_style_context_set_state (style, state); - - va_start (ap, first_class); - for (name = first_class; name; name = va_arg (ap, const char *)) - gtk_widget_path_iter_add_class (path, -1, name); - va_end (ap); - - gtk_style_context_set_path (style, path); - gtk_widget_path_unref (path); - - gtk_style_context_add_provider (style, GTK_STYLE_PROVIDER (provider), - GTK_STYLE_PROVIDER_PRIORITY_SETTINGS); - - return style; -} - -static inline GtkCssProvider * -get_css_provider_for_theme_name (const gchar *theme_name, - const gchar *variant) -{ - static GtkCssProvider *default_provider = NULL; - - if (!theme_name || *theme_name == '\0') - { - if (G_UNLIKELY (default_provider == NULL)) - default_provider = gtk_css_provider_new (); - - return default_provider; - } - - return gtk_css_provider_get_named (theme_name, variant); -} - -MetaStyleInfo * -meta_theme_create_style_info (GdkScreen *screen, - const gchar *variant) -{ - MetaStyleInfo *style_info; - GtkCssProvider *provider; - char *theme_name; - - g_object_get (gtk_settings_get_for_screen (screen), - "gtk-theme-name", &theme_name, - NULL); - - provider = get_css_provider_for_theme_name (theme_name, variant); - g_free (theme_name); - - style_info = g_new0 (MetaStyleInfo, 1); - style_info->refcount = 1; - - style_info->styles[META_STYLE_ELEMENT_WINDOW] = - create_style_context (META_TYPE_FRAMES, - NULL, - provider, - "window", - GTK_STYLE_CLASS_BACKGROUND, - "ssd", - NULL); - style_info->styles[META_STYLE_ELEMENT_FRAME] = - create_style_context (META_TYPE_FRAMES, - style_info->styles[META_STYLE_ELEMENT_WINDOW], - provider, - "decoration", - NULL); - style_info->styles[META_STYLE_ELEMENT_TITLEBAR] = - create_style_context (GTK_TYPE_HEADER_BAR, - style_info->styles[META_STYLE_ELEMENT_FRAME], - provider, - "headerbar", - GTK_STYLE_CLASS_TITLEBAR, - GTK_STYLE_CLASS_HORIZONTAL, - "default-decoration", - NULL); - style_info->styles[META_STYLE_ELEMENT_TITLE] = - create_style_context (GTK_TYPE_LABEL, - style_info->styles[META_STYLE_ELEMENT_TITLEBAR], - provider, - "label", - GTK_STYLE_CLASS_TITLE, - NULL); - style_info->styles[META_STYLE_ELEMENT_BUTTON] = - create_style_context (GTK_TYPE_BUTTON, - style_info->styles[META_STYLE_ELEMENT_TITLEBAR], - provider, - "button", - "titlebutton", - NULL); - style_info->styles[META_STYLE_ELEMENT_IMAGE] = - create_style_context (GTK_TYPE_IMAGE, - style_info->styles[META_STYLE_ELEMENT_BUTTON], - provider, - "image", - NULL); - return style_info; -} - -MetaStyleInfo * -meta_style_info_ref (MetaStyleInfo *style_info) -{ - g_return_val_if_fail (style_info != NULL, NULL); - g_return_val_if_fail (style_info->refcount > 0, NULL); - - g_atomic_int_inc ((volatile int *)&style_info->refcount); - return style_info; -} - -void -meta_style_info_unref (MetaStyleInfo *style_info) -{ - g_return_if_fail (style_info != NULL); - g_return_if_fail (style_info->refcount > 0); - - if (g_atomic_int_dec_and_test ((volatile int *)&style_info->refcount)) - { - int i; - for (i = 0; i < META_STYLE_ELEMENT_LAST; i++) - g_object_unref (style_info->styles[i]); - g_free (style_info); - } -} - -static void -add_toplevel_class (GtkStyleContext *style, - const char *class_name) -{ - if (gtk_style_context_get_parent (style)) - { - GtkWidgetPath *path; - - path = gtk_widget_path_copy (gtk_style_context_get_path (style)); - gtk_widget_path_iter_add_class (path, 0, class_name); - gtk_style_context_set_path (style, path); - gtk_widget_path_unref (path); - } - else - gtk_style_context_add_class (style, class_name); -} - -static void -remove_toplevel_class (GtkStyleContext *style, - const char *class_name) -{ - if (gtk_style_context_get_parent (style)) - { - GtkWidgetPath *path; - - path = gtk_widget_path_copy (gtk_style_context_get_path (style)); - gtk_widget_path_iter_remove_class (path, 0, class_name); - gtk_style_context_set_path (style, path); - gtk_widget_path_unref (path); - } - else - gtk_style_context_remove_class (style, class_name); -} - -void -meta_style_info_set_flags (MetaStyleInfo *style_info, - MetaFrameFlags flags) -{ - GtkStyleContext *style; - const char *class_name = NULL; - gboolean backdrop; - GtkStateFlags state; - int i; - - backdrop = !(flags & META_FRAME_HAS_FOCUS); - - if (flags & META_FRAME_MAXIMIZED) - class_name = "maximized"; - else if (flags & META_FRAME_TILED_LEFT || - flags & META_FRAME_TILED_RIGHT) - class_name = "tiled"; - - for (i = 0; i < META_STYLE_ELEMENT_LAST; i++) - { - style = style_info->styles[i]; - - state = gtk_style_context_get_state (style); - if (backdrop) - gtk_style_context_set_state (style, state | GTK_STATE_FLAG_BACKDROP); - else - gtk_style_context_set_state (style, state & ~GTK_STATE_FLAG_BACKDROP); - - remove_toplevel_class (style, "maximized"); - remove_toplevel_class (style, "tiled"); - - if (class_name) - add_toplevel_class (style, class_name); - } -} - -PangoFontDescription* -meta_style_info_create_font_desc (MetaStyleInfo *style_info) -{ - PangoFontDescription *font_desc; - const PangoFontDescription *override = meta_prefs_get_titlebar_font (); - GtkStyleContext *context = style_info->styles[META_STYLE_ELEMENT_TITLE]; - - gtk_style_context_get (context, - gtk_style_context_get_state (context), - "font", &font_desc, NULL); - - if (override) - pango_font_description_merge (font_desc, override, TRUE); - - return font_desc; -} - -void -meta_theme_draw_frame (MetaTheme *theme, - MetaStyleInfo *style_info, - cairo_t *cr, - MetaFrameType type, - MetaFrameFlags flags, - int client_width, - int client_height, - PangoLayout *title_layout, - int text_height, - const MetaButtonLayout *button_layout, - MetaButtonState button_states[META_BUTTON_TYPE_LAST], - cairo_surface_t *mini_icon) -{ - MetaFrameGeometry fgeom; - MetaFrameLayout *layout; - - g_return_if_fail (type < META_FRAME_TYPE_LAST); - - layout = theme->layouts[type]; - - /* Parser is not supposed to allow this currently */ - if (layout == NULL) - return; - - meta_frame_layout_calc_geometry (layout, - style_info, - text_height, - flags, - client_width, client_height, - button_layout, - type, - &fgeom, - theme); - - meta_frame_layout_draw_with_style (layout, - style_info, - cr, - &fgeom, - title_layout, - flags, - button_states, - mini_icon); -} - -void -meta_theme_get_frame_borders (MetaTheme *theme, - MetaStyleInfo *style_info, - MetaFrameType type, - int text_height, - MetaFrameFlags flags, - MetaFrameBorders *borders) -{ - MetaFrameLayout *layout; - - g_return_if_fail (type < META_FRAME_TYPE_LAST); - - layout = theme->layouts[type]; - - meta_frame_borders_clear (borders); - - /* Parser is not supposed to allow this currently */ - if (layout == NULL) - return; - - meta_frame_layout_sync_with_style (layout, style_info, flags); - - meta_frame_layout_get_borders (layout, - text_height, - flags, type, - borders); -} - -void -meta_theme_calc_geometry (MetaTheme *theme, - MetaStyleInfo *style_info, - MetaFrameType type, - int text_height, - MetaFrameFlags flags, - int client_width, - int client_height, - const MetaButtonLayout *button_layout, - MetaFrameGeometry *fgeom) -{ - MetaFrameLayout *layout; - - g_return_if_fail (type < META_FRAME_TYPE_LAST); - - layout = theme->layouts[type]; - - /* Parser is not supposed to allow this currently */ - if (layout == NULL) - return; - - meta_frame_layout_calc_geometry (layout, - style_info, - text_height, - flags, - client_width, client_height, - button_layout, - type, - fgeom, - theme); -} - -/** - * meta_pango_font_desc_get_text_height: - * @font_desc: the font - * @context: the context of the font - * - * Returns the height of the letters in a particular font. - * - * Returns: the height of the letters - */ -int -meta_pango_font_desc_get_text_height (const PangoFontDescription *font_desc, - PangoContext *context) -{ - PangoFontMetrics *metrics; - PangoLanguage *lang; - int retval; - - lang = pango_context_get_language (context); - metrics = pango_context_get_metrics (context, font_desc, lang); - - retval = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) + - pango_font_metrics_get_descent (metrics)); - - pango_font_metrics_unref (metrics); - - return retval; -} diff --git a/src/ui/ui.c b/src/ui/ui.c deleted file mode 100644 index dd52a0c57..000000000 --- a/src/ui/ui.c +++ /dev/null @@ -1,240 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Mutter interface for talking to GTK+ UI module */ - -/* - * Copyright (C) 2002 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, see . - */ - -#include "config.h" - -#include -#include -#include - -#include "meta/prefs.h" -#include "meta/util.h" -#include "ui/frames.h" -#include "ui/theme-private.h" -#include "ui/ui.h" -#include "x11/meta-x11-display-private.h" -#include "x11/meta-x11-window-control.h" - -struct _MetaUI -{ - Display *xdisplay; - MetaFrames *frames; - - /* For double-click tracking */ - gint button_click_number; - Window button_click_window; - int button_click_x; - int button_click_y; - guint32 button_click_time; -}; - -MetaUI * -meta_ui_new (MetaX11Display *x11_display) -{ - MetaUI *ui; - - if (!gtk_init_check (NULL, NULL)) - meta_fatal ("Unable to initialize GTK"); - - g_assert (x11_display->gdk_display == gdk_display_get_default ()); - - ui = g_new0 (MetaUI, 1); - ui->xdisplay = x11_display->xdisplay; - - ui->frames = meta_frames_new (x11_display); - /* GTK+ needs the frame-sync protocol to work in order to properly - * handle style changes. This means that the dummy widget we create - * to get the style for title bars actually needs to be mapped - * and fully tracked as a MetaWindow. Horrible, but mostly harmless - - * the window is a 1x1 override redirect window positioned offscreen. - */ - gtk_widget_show (GTK_WIDGET (ui->frames)); - - g_object_set_data (G_OBJECT (x11_display->gdk_display), "meta-ui", ui); - - return ui; -} - -void -meta_ui_free (MetaUI *ui) -{ - GdkDisplay *gdk_display; - - gtk_widget_destroy (GTK_WIDGET (ui->frames)); - - gdk_display = gdk_x11_lookup_xdisplay (ui->xdisplay); - g_object_set_data (G_OBJECT (gdk_display), "meta-ui", NULL); - - g_free (ui); -} - -static void -set_background_none (Display *xdisplay, - Window xwindow) -{ - XSetWindowAttributes attrs; - - attrs.background_pixmap = None; - XChangeWindowAttributes (xdisplay, xwindow, - CWBackPixmap, &attrs); -} - -MetaUIFrame * -meta_ui_create_frame (MetaUI *ui, - Display *xdisplay, - MetaWindow *meta_window, - Visual *xvisual, - gint x, - gint y, - gint width, - gint height, - gulong *create_serial) -{ - GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay); - GdkScreen *screen; - GdkWindowAttr attrs; - gint attributes_mask; - GdkWindow *window; - GdkVisual *visual; - - screen = gdk_display_get_default_screen (display); - - /* Default depth/visual handles clients with weird visuals; they can - * always be children of the root depth/visual obviously, but - * e.g. DRI games can't be children of a parent that has the same - * visual as the client. - */ - if (!xvisual) - visual = gdk_screen_get_system_visual (screen); - else - { - visual = gdk_x11_screen_lookup_visual (screen, - XVisualIDFromVisual (xvisual)); - } - - attrs.title = NULL; - - attrs.event_mask = GDK_EXPOSURE_MASK; - attrs.x = x; - attrs.y = y; - attrs.wclass = GDK_INPUT_OUTPUT; - attrs.visual = visual; - attrs.window_type = GDK_WINDOW_CHILD; - attrs.cursor = NULL; - attrs.wmclass_name = NULL; - attrs.wmclass_class = NULL; - attrs.override_redirect = FALSE; - - attrs.width = width; - attrs.height = height; - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; - - /* We make an assumption that gdk_window_new() is going to call - * XCreateWindow as it's first operation; this seems to be true currently - * as long as you pass in a colormap. - */ - if (create_serial) - *create_serial = XNextRequest (xdisplay); - window = - gdk_window_new (gdk_screen_get_root_window(screen), - &attrs, attributes_mask); - - gdk_window_resize (window, width, height); - set_background_none (xdisplay, GDK_WINDOW_XID (window)); - - return meta_frames_manage_window (ui->frames, meta_window, GDK_WINDOW_XID (window), window); -} - -void -meta_ui_map_frame (MetaUI *ui, - Window xwindow) -{ - GdkWindow *window; - GdkDisplay *display; - - display = gdk_x11_lookup_xdisplay (ui->xdisplay); - window = gdk_x11_window_lookup_for_display (display, xwindow); - - if (window) - gdk_window_show_unraised (window); -} - -void -meta_ui_unmap_frame (MetaUI *ui, - Window xwindow) -{ - GdkWindow *window; - GdkDisplay *display; - - display = gdk_x11_lookup_xdisplay (ui->xdisplay); - window = gdk_x11_window_lookup_for_display (display, xwindow); - - if (window) - gdk_window_hide (window); -} - -gboolean -meta_ui_window_should_not_cause_focus (Display *xdisplay, - Window xwindow) -{ - GdkWindow *window; - GdkDisplay *display; - - display = gdk_x11_lookup_xdisplay (xdisplay); - window = gdk_x11_window_lookup_for_display (display, xwindow); - - /* we shouldn't cause focus if we're an override redirect - * toplevel which is not foreign - */ - if (window && gdk_window_get_window_type (window) == GDK_WINDOW_TEMP) - return TRUE; - else - return FALSE; -} - -gboolean -meta_ui_window_is_widget (MetaUI *ui, - Window xwindow) -{ - GdkDisplay *display; - GdkWindow *window; - - display = gdk_x11_lookup_xdisplay (ui->xdisplay); - window = gdk_x11_window_lookup_for_display (display, xwindow); - - if (window) - { - void *user_data = NULL; - gdk_window_get_user_data (window, &user_data); - return user_data != NULL && user_data != ui->frames; - } - else - return FALSE; -} - -gboolean -meta_ui_window_is_dummy (MetaUI *ui, - Window xwindow) -{ - GdkWindow *frames_window = gtk_widget_get_window (GTK_WIDGET (ui->frames)); - return xwindow == gdk_x11_window_get_xid (frames_window); -} diff --git a/src/ui/ui.h b/src/ui/ui.h deleted file mode 100644 index b5fbad0eb..000000000 --- a/src/ui/ui.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Mutter interface for talking to GTK+ UI module */ - -/* - * 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, see . - */ - -#ifndef META_UI_H -#define META_UI_H - -#include -#include -#include -#include -#include - -#include "core/util-private.h" -#include "meta/types.h" - -typedef struct _MetaUI MetaUI; -typedef struct _MetaUIFrame MetaUIFrame; - -typedef gboolean (* MetaEventFunc) (XEvent *xevent, gpointer data); - -MetaUI *meta_ui_new (MetaX11Display *x11_display); -void meta_ui_free (MetaUI *ui); - -MetaUIFrame * meta_ui_create_frame (MetaUI *ui, - Display *xdisplay, - MetaWindow *meta_window, - Visual *xvisual, - gint x, - gint y, - gint width, - gint height, - gulong *create_serial); - -/* GDK insists on tracking map/unmap */ -void meta_ui_map_frame (MetaUI *ui, - Window xwindow); -void meta_ui_unmap_frame (MetaUI *ui, - Window xwindow); - -gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay, - Window xwindow); - -gboolean meta_ui_window_is_widget (MetaUI *ui, - Window xwindow); - -META_EXPORT_TEST -gboolean meta_ui_window_is_dummy (MetaUI *ui, - Window xwindow); - -#endif diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h index 1030a2947..f9a37c51f 100644 --- a/src/x11/meta-x11-display-private.h +++ b/src/x11/meta-x11-display-private.h @@ -36,7 +36,6 @@ #include "meta/meta-x11-display.h" #include "meta-startup-notification-x11.h" #include "meta-x11-stack-private.h" -#include "ui/ui.h" #include "x11/meta-sync-counter.h" typedef struct _MetaGroupPropHooks MetaGroupPropHooks; @@ -130,8 +129,6 @@ struct _MetaX11Display GPtrArray *alarm_filters; - MetaUI *ui; - GSubprocess *frames_client; GCancellable *frames_client_cancellable; diff --git a/src/x11/xprops.c b/src/x11/xprops.c index 1b97b2648..49a65b674 100644 --- a/src/x11/xprops.c +++ b/src/x11/xprops.c @@ -90,7 +90,6 @@ from The Open Group. #include "core/util-private.h" #include "core/window-private.h" #include "meta/meta-x11-errors.h" -#include "ui/ui.h" #include "x11/meta-x11-display-private.h" #include "x11/mutter-Xatomtype.h"