Remove legacy theming API

Since the move to GTK+ toplevels, it required removing the preview-widget
and theme-viewer parts of the code. (They didn't work with the new CSS
stuff anyway... shhh..)
This commit is contained in:
Jasper St. Pierre 2012-05-05 02:48:14 -03:00
parent 8d8e0cb055
commit 7623b97399
20 changed files with 239 additions and 14285 deletions

View File

@ -140,13 +140,7 @@ libmutter_la_SOURCES = \
ui/tabpopup.h \
ui/tile-preview.c \
ui/tile-preview.h \
ui/theme-parser.c \
ui/theme.c \
meta/theme.h \
ui/theme-private.h \
ui/ui.c \
meta/preview-widget.h \
ui/preview-widget.c \
$(mutter_built_sources)
libmutter_la_LDFLAGS = -no-undefined
@ -171,7 +165,6 @@ libmutterinclude_base_headers = \
meta/meta-window-actor.h \
meta/prefs.h \
meta/screen.h \
meta/theme.h \
meta/types.h \
meta/util.h \
meta/window.h \
@ -180,7 +173,6 @@ libmutterinclude_base_headers = \
# Excluded from scanning for introspection but installed
# atomnames.h: macros cause problems for scanning process
libmutterinclude_extra_headers = \
meta/preview-widget.h \
meta/atomnames.h
libmutterincludedir = $(includedir)/mutter/meta
@ -189,10 +181,7 @@ libmutterinclude_HEADERS = \
$(libmutterinclude_base_headers) \
$(libmutterinclude_extra_headers)
mutter_theme_viewer_SOURCES= \
ui/theme-viewer.c
bin_PROGRAMS=mutter mutter-theme-viewer
bin_PROGRAMS=mutter
mutter_SOURCES = core/mutter.c
mutter_LDADD = $(MUTTER_LIBS) libmutter.la
@ -230,8 +219,6 @@ Meta-$(api_version).gir: libmutter.la
endif
mutter_theme_viewer_LDADD= $(MUTTER_LIBS) libmutter.la
testboxes_SOURCES = core/testboxes.c
testasyncgetprop_SOURCES = core/testasyncgetprop.c

View File

@ -2571,9 +2571,6 @@ event_callback (XEvent *event,
else if (event->xclient.message_type ==
display->atom__MUTTER_RELOAD_THEME_MESSAGE)
{
meta_verbose ("Received reload theme request\n");
meta_ui_set_current_theme (meta_prefs_get_theme (),
TRUE);
meta_display_retheme_all ();
}
else if (event->xclient.message_type ==

View File

@ -118,11 +118,6 @@ meta_window_ensure_frame (MetaWindow *window)
meta_display_register_x_window (window->display, &frame->xwindow, window);
/* Now that frame->xwindow is registered with window, we can set its
* style and background.
*/
meta_ui_update_frame_style (window->screen->ui, frame->xwindow);
meta_ui_realize_frame_window (window->screen->ui, frame->xwindow);
if (window->title)
@ -163,7 +158,6 @@ meta_window_ensure_frame (MetaWindow *window)
/* FIXME handle this error */
meta_error_trap_pop (window->display);
/* Move keybindings to frame instead of window */
meta_window_grab_keys (window);

View File

@ -477,42 +477,6 @@ meta_run (void)
if (g_getenv ("MUTTER_G_FATAL_WARNINGS") != NULL)
g_log_set_always_fatal (G_LOG_LEVEL_MASK);
meta_ui_set_current_theme (meta_prefs_get_theme (), FALSE);
/* Try to find some theme that'll work if the theme preference
* doesn't exist. First try Simple (the default theme) then just
* try anything in the themes directory.
*/
if (!meta_ui_have_a_theme ())
meta_ui_set_current_theme ("Simple", FALSE);
if (!meta_ui_have_a_theme ())
{
const char *dir_entry = NULL;
GError *err = NULL;
GDir *themes_dir = NULL;
if (!(themes_dir = g_dir_open (MUTTER_DATADIR"/themes", 0, &err)))
{
meta_fatal (_("Failed to scan themes directory: %s\n"), err->message);
g_error_free (err);
}
else
{
while (((dir_entry = g_dir_read_name (themes_dir)) != NULL) &&
(!meta_ui_have_a_theme ()))
{
meta_ui_set_current_theme (dir_entry, FALSE);
}
g_dir_close (themes_dir);
}
}
if (!meta_ui_have_a_theme ())
meta_fatal (_("Could not find a theme! Be sure %s exists and contains the usual themes.\n"),
MUTTER_DATADIR"/themes");
/* Connect to SM as late as possible - but before managing display,
* or we might try to manage a window before we have the session
* info
@ -588,9 +552,7 @@ prefs_changed_callback (MetaPreference pref,
{
switch (pref)
{
case META_PREF_THEME:
case META_PREF_DRAGGABLE_BORDER_WIDTH:
meta_ui_set_current_theme (meta_prefs_get_theme (), FALSE);
meta_display_retheme_all ();
break;

View File

@ -73,7 +73,6 @@ static GDesktopFocusMode focus_mode = G_DESKTOP_FOCUS_MODE_CLICK;
static GDesktopFocusNewWindows focus_new_windows = G_DESKTOP_FOCUS_NEW_WINDOWS_SMART;
static gboolean raise_on_click = TRUE;
static gboolean attach_modal_dialogs = FALSE;
static char* current_theme = NULL;
static int num_workspaces = 4;
static GDesktopTitlebarAction action_double_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE;
static GDesktopTitlebarAction action_middle_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_LOWER;
@ -124,7 +123,6 @@ static void queue_changed (MetaPreference pref);
static void maybe_give_disable_workarounds_warning (void);
static gboolean theme_name_handler (GVariant*, gpointer*, gpointer);
static gboolean mouse_button_mods_handler (GVariant*, gpointer*, gpointer);
static gboolean button_layout_handler (GVariant*, gpointer*, gpointer);
@ -359,14 +357,6 @@ static MetaStringPreference preferences_string[] =
mouse_button_mods_handler,
NULL,
},
{
{ "theme",
SCHEMA_GENERAL,
META_PREF_THEME,
},
theme_name_handler,
NULL,
},
{
{ "button-layout",
SCHEMA_GENERAL,
@ -1080,12 +1070,6 @@ meta_prefs_get_raise_on_click (void)
return raise_on_click || focus_mode == G_DESKTOP_FOCUS_MODE_CLICK;
}
const char*
meta_prefs_get_theme (void)
{
return current_theme;
}
const char*
meta_prefs_get_cursor_theme (void)
{
@ -1103,31 +1087,6 @@ meta_prefs_get_cursor_size (void)
/* Handlers for string preferences. */
/****************************************************************************/
static gboolean
theme_name_handler (GVariant *value,
gpointer *result,
gpointer data)
{
const gchar *string_value;
*result = NULL; /* ignored */
string_value = g_variant_get_string (value, NULL);
if (!string_value || !*string_value)
return FALSE;
if (g_strcmp0 (current_theme, string_value) != 0)
{
if (current_theme)
g_free (current_theme);
current_theme = g_strdup (string_value);
queue_changed (META_PREF_THEME);
}
return TRUE;
}
static gboolean
mouse_button_mods_handler (GVariant *value,
gpointer *result,
@ -1468,9 +1427,6 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_RAISE_ON_CLICK:
return "RAISE_ON_CLICK";
case META_PREF_THEME:
return "THEME";
case META_PREF_NUM_WORKSPACES:
return "NUM_WORKSPACES";

View File

@ -926,5 +926,43 @@ meta_later_remove (guint later_id)
}
}
/**
* meta_frame_type_to_string:
*
* Converts a frame type enum value to the name string that would
* appear in the theme definition file.
*
* Return value: the string value
*/
const char*
meta_frame_type_to_string (MetaFrameType type)
{
switch (type)
{
case META_FRAME_TYPE_NORMAL:
return "normal";
case META_FRAME_TYPE_DIALOG:
return "dialog";
case META_FRAME_TYPE_MODAL_DIALOG:
return "modal_dialog";
case META_FRAME_TYPE_UTILITY:
return "utility";
case META_FRAME_TYPE_MENU:
return "menu";
case META_FRAME_TYPE_BORDER:
return "border";
case META_FRAME_TYPE_ATTACHED:
return "attached";
#if 0
case META_FRAME_TYPE_TOOLBAR:
return "toolbar";
#endif
case META_FRAME_TYPE_LAST:
break;
}
return "<unknown>";
}
/* eof util.c */

View File

@ -1588,7 +1588,7 @@ reload_gtk_theme_variant (MetaWindow *window,
window->gtk_theme_variant = g_strdup (requested_variant);
if (window->frame)
meta_ui_update_frame_style (window->screen->ui, window->frame->xwindow);
meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow);
}
}
@ -1616,7 +1616,7 @@ reload_gtk_hide_titlebar_when_maximized (MetaWindow *window,
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
if (window->frame)
meta_ui_update_frame_style (window->screen->ui, window->frame->xwindow);
meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow);
}
}

View File

@ -45,7 +45,6 @@ typedef enum
META_PREF_ACTION_RIGHT_CLICK_TITLEBAR,
META_PREF_AUTO_RAISE,
META_PREF_AUTO_RAISE_DELAY,
META_PREF_THEME,
META_PREF_NUM_WORKSPACES,
META_PREF_DYNAMIC_WORKSPACES,
META_PREF_APPLICATION_BASED,
@ -90,7 +89,6 @@ GDesktopFocusMode meta_prefs_get_focus_mode (void);
GDesktopFocusNewWindows meta_prefs_get_focus_new_windows (void);
gboolean meta_prefs_get_attach_modal_dialogs (void);
gboolean meta_prefs_get_raise_on_click (void);
const char* meta_prefs_get_theme (void);
/* returns NULL if GTK default should be used */
const PangoFontDescription* meta_prefs_get_titlebar_font (void);
int meta_prefs_get_num_workspaces (void);

View File

@ -1,81 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Metacity theme preview widget */
/*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <config.h>
#include <meta/common.h>
#include <meta/theme.h>
#include <gtk/gtk.h>
#ifndef META_PREVIEW_WIDGET_H
#define META_PREVIEW_WIDGET_H
#define META_TYPE_PREVIEW (meta_preview_get_type ())
#define META_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_PREVIEW, MetaPreview))
#define META_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_PREVIEW, MetaPreviewClass))
#define META_IS_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_PREVIEW))
#define META_IS_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_PREVIEW))
#define META_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_PREVIEW, MetaPreviewClass))
typedef struct _MetaPreview MetaPreview;
typedef struct _MetaPreviewClass MetaPreviewClass;
struct _MetaPreview
{
GtkBin bin;
MetaTheme *theme;
char *title;
MetaFrameType type;
MetaFrameFlags flags;
MetaFrameBorders borders;
guint borders_cached : 1;
MetaButtonLayout button_layout;
};
struct _MetaPreviewClass
{
GtkBinClass parent_class;
};
GType meta_preview_get_type (void) G_GNUC_CONST;
GtkWidget* meta_preview_new (void);
void meta_preview_set_theme (MetaPreview *preview,
MetaTheme *theme);
void meta_preview_set_title (MetaPreview *preview,
const char *title);
void meta_preview_set_frame_type (MetaPreview *preview,
MetaFrameType type);
void meta_preview_set_frame_flags (MetaPreview *preview,
MetaFrameFlags flags);
void meta_preview_set_button_layout (MetaPreview *preview,
const MetaButtonLayout *button_layout);
GdkPixbuf* meta_preview_get_icon (void);
GdkPixbuf* meta_preview_get_mini_icon (void);
#endif

View File

@ -1,47 +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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_THEME_H
#define META_THEME_H
#include <glib.h>
/**
* MetaTheme:
*
*/
typedef struct _MetaTheme MetaTheme;
MetaTheme* meta_theme_get_current (void);
void meta_theme_set_current (const char *name,
gboolean force_reload);
MetaTheme* meta_theme_new (void);
void meta_theme_free (MetaTheme *theme);
gboolean meta_theme_validate (MetaTheme *theme,
GError **error);
MetaTheme* meta_theme_load (const char *theme_name,
GError **err);
#endif

View File

@ -26,7 +26,6 @@
*/
#include "draw-workspace.h"
#include "theme-private.h"
static void
@ -75,21 +74,15 @@ draw_window (GtkWidget *widget,
{
GdkPixbuf *icon;
int icon_x, icon_y, icon_w, icon_h;
gboolean is_active;
GdkRGBA color;
GtkStyleContext *style;
is_active = win->is_active;
cairo_save (cr);
cairo_rectangle (cr, winrect->x, winrect->y, winrect->width, winrect->height);
cairo_clip (cr);
style = gtk_widget_get_style_context (widget);
if (is_active)
meta_gtk_style_get_light_color (style, state, &color);
else
gtk_style_context_get_background_color (style, state, &color);
gdk_cairo_set_source_rgba (cr, &color);
@ -197,7 +190,7 @@ wnck_draw_workspace (GtkWidget *widget,
{
GdkRGBA color;
meta_gtk_style_get_dark_color (style,state, &color);
gtk_style_context_get_background_color (style, state, &color);
gdk_cairo_set_source_rgba (cr, &color);
cairo_rectangle (cr, x, y, width, height);
cairo_fill (cr);

View File

@ -1,422 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Metacity theme preview widget */
/*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#define _GNU_SOURCE
#define _XOPEN_SOURCE 600 /* for the maths routines over floats */
#include <math.h>
#include <gtk/gtk.h>
#include <meta/preview-widget.h>
#include "theme-private.h"
static void meta_preview_get_preferred_width (GtkWidget *widget,
gint *minimum,
gint *natural);
static void meta_preview_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural);
static void meta_preview_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static gboolean meta_preview_draw (GtkWidget *widget,
cairo_t *cr);
static void meta_preview_finalize (GObject *object);
G_DEFINE_TYPE (MetaPreview, meta_preview, GTK_TYPE_BIN);
static void
meta_preview_class_init (MetaPreviewClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class;
widget_class = (GtkWidgetClass*) class;
gobject_class->finalize = meta_preview_finalize;
widget_class->draw = meta_preview_draw;
widget_class->get_preferred_width = meta_preview_get_preferred_width;
widget_class->get_preferred_height = meta_preview_get_preferred_height;
widget_class->size_allocate = meta_preview_size_allocate;
gtk_container_class_handle_border_width (GTK_CONTAINER_CLASS (class));
}
static void
meta_preview_init (MetaPreview *preview)
{
int i;
gtk_widget_set_has_window (GTK_WIDGET (preview), FALSE);
i = 0;
while (i < MAX_BUTTONS_PER_CORNER)
{
preview->button_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
preview->button_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
++i;
}
preview->button_layout.left_buttons[0] = META_BUTTON_FUNCTION_MENU;
preview->button_layout.right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE;
preview->button_layout.right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE;
preview->button_layout.right_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
preview->type = META_FRAME_TYPE_NORMAL;
preview->flags =
META_FRAME_ALLOWS_DELETE |
META_FRAME_ALLOWS_MENU |
META_FRAME_ALLOWS_MINIMIZE |
META_FRAME_ALLOWS_MAXIMIZE |
META_FRAME_ALLOWS_VERTICAL_RESIZE |
META_FRAME_ALLOWS_HORIZONTAL_RESIZE |
META_FRAME_HAS_FOCUS |
META_FRAME_ALLOWS_SHADE |
META_FRAME_ALLOWS_MOVE;
preview->borders_cached = FALSE;
}
GtkWidget*
meta_preview_new (void)
{
MetaPreview *preview;
preview = g_object_new (META_TYPE_PREVIEW, NULL);
return GTK_WIDGET (preview);
}
static void
meta_preview_finalize (GObject *object)
{
MetaPreview *preview;
preview = META_PREVIEW (object);
g_free (preview->title);
preview->title = NULL;
G_OBJECT_CLASS (meta_preview_parent_class)->finalize (object);
}
static void
ensure_info (MetaPreview *preview)
{
GtkWidget *widget;
widget = GTK_WIDGET (preview);
if (!preview->borders_cached)
{
if (preview->theme)
meta_theme_get_frame_borders (preview->theme,
meta_theme_get_variant (preview->theme, NULL)->style_context,
preview->type,
preview->flags,
&preview->borders);
else
meta_frame_borders_clear (&preview->borders);
preview->borders_cached = TRUE;
}
}
static gboolean
meta_preview_draw (GtkWidget *widget,
cairo_t *cr)
{
MetaPreview *preview = META_PREVIEW (widget);
GtkAllocation allocation;
gtk_widget_get_allocation (widget, &allocation);
if (preview->theme)
{
int client_width;
int client_height;
MetaButtonState button_states[META_BUTTON_TYPE_LAST] =
{
META_BUTTON_STATE_NORMAL,
META_BUTTON_STATE_NORMAL,
META_BUTTON_STATE_NORMAL,
META_BUTTON_STATE_NORMAL
};
ensure_info (preview);
cairo_save (cr);
client_width = allocation.width - preview->borders.total.left - preview->borders.total.right;
client_height = allocation.height - preview->borders.total.top - preview->borders.total.bottom;
if (client_width < 0)
client_width = 1;
if (client_height < 0)
client_height = 1;
meta_theme_draw_frame_with_style (preview->theme,
gtk_widget_get_style_context (widget),
cr,
preview->type,
preview->flags,
client_width,
client_height,
&preview->button_layout,
button_states,
meta_preview_get_mini_icon (),
meta_preview_get_icon ());
cairo_restore (cr);
}
/* draw child */
return GTK_WIDGET_CLASS (meta_preview_parent_class)->draw (widget, cr);
}
#define NO_CHILD_WIDTH 80
#define NO_CHILD_HEIGHT 20
static void
meta_preview_get_preferred_width (GtkWidget *widget,
gint *minimum,
gint *natural)
{
MetaPreview *preview;
GtkWidget *child;
preview = META_PREVIEW (widget);
ensure_info (preview);
*minimum = *natural = preview->borders.total.left + preview->borders.total.right;
child = gtk_bin_get_child (GTK_BIN (preview));
if (child && gtk_widget_get_visible (child))
{
gint child_min, child_nat;
gtk_widget_get_preferred_width (child, &child_min, &child_nat);
*minimum += child_min;
*natural += child_nat;
}
else
{
*minimum += NO_CHILD_WIDTH;
*natural += NO_CHILD_WIDTH;
}
}
static void
meta_preview_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural)
{
MetaPreview *preview;
GtkWidget *child;
preview = META_PREVIEW (widget);
ensure_info (preview);
*minimum = *natural = preview->borders.total.top + preview->borders.total.bottom;
child = gtk_bin_get_child (GTK_BIN (preview));
if (child && gtk_widget_get_visible (child))
{
gint child_min, child_nat;
gtk_widget_get_preferred_height (child, &child_min, &child_nat);
*minimum += child_min;
*natural += child_nat;
}
else
{
*minimum += NO_CHILD_HEIGHT;
*natural += NO_CHILD_HEIGHT;
}
}
static void
meta_preview_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
MetaPreview *preview;
GtkAllocation widget_allocation, child_allocation;
GtkWidget *child;
preview = META_PREVIEW (widget);
ensure_info (preview);
gtk_widget_set_allocation (widget, allocation);
child = gtk_bin_get_child (GTK_BIN (widget));
if (child && gtk_widget_get_visible (child))
{
gtk_widget_get_allocation (widget, &widget_allocation);
child_allocation.x = widget_allocation.x + preview->borders.total.left;
child_allocation.y = widget_allocation.y + preview->borders.total.top;
child_allocation.width = MAX (1, widget_allocation.width - preview->borders.total.left - preview->borders.total.right);
child_allocation.height = MAX (1, widget_allocation.height - preview->borders.total.top - preview->borders.total.bottom);
gtk_widget_size_allocate (child, &child_allocation);
}
}
static void
clear_cache (MetaPreview *preview)
{
preview->borders_cached = FALSE;
}
void
meta_preview_set_theme (MetaPreview *preview,
MetaTheme *theme)
{
g_return_if_fail (META_IS_PREVIEW (preview));
preview->theme = theme;
clear_cache (preview);
gtk_widget_queue_resize (GTK_WIDGET (preview));
}
void
meta_preview_set_title (MetaPreview *preview,
const char *title)
{
g_return_if_fail (META_IS_PREVIEW (preview));
g_free (preview->title);
preview->title = g_strdup (title);
clear_cache (preview);
gtk_widget_queue_resize (GTK_WIDGET (preview));
}
void
meta_preview_set_frame_type (MetaPreview *preview,
MetaFrameType type)
{
g_return_if_fail (META_IS_PREVIEW (preview));
preview->type = type;
clear_cache (preview);
gtk_widget_queue_resize (GTK_WIDGET (preview));
}
void
meta_preview_set_frame_flags (MetaPreview *preview,
MetaFrameFlags flags)
{
g_return_if_fail (META_IS_PREVIEW (preview));
preview->flags = flags;
clear_cache (preview);
gtk_widget_queue_resize (GTK_WIDGET (preview));
}
void
meta_preview_set_button_layout (MetaPreview *preview,
const MetaButtonLayout *button_layout)
{
g_return_if_fail (META_IS_PREVIEW (preview));
preview->button_layout = *button_layout;
gtk_widget_queue_draw (GTK_WIDGET (preview));
}
GdkPixbuf*
meta_preview_get_icon (void)
{
static GdkPixbuf *default_icon = NULL;
if (default_icon == NULL)
{
GtkIconTheme *theme;
gboolean icon_exists;
theme = gtk_icon_theme_get_default ();
icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
if (icon_exists)
default_icon = gtk_icon_theme_load_icon (theme,
META_DEFAULT_ICON_NAME,
META_ICON_WIDTH,
0,
NULL);
else
default_icon = gtk_icon_theme_load_icon (theme,
"gtk-missing-image",
META_ICON_WIDTH,
0,
NULL);
g_assert (default_icon);
}
return default_icon;
}
GdkPixbuf*
meta_preview_get_mini_icon (void)
{
static GdkPixbuf *default_icon = NULL;
if (default_icon == NULL)
{
GtkIconTheme *theme;
gboolean icon_exists;
theme = gtk_icon_theme_get_default ();
icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
if (icon_exists)
default_icon = gtk_icon_theme_load_icon (theme,
META_DEFAULT_ICON_NAME,
META_MINI_ICON_WIDTH,
0,
NULL);
else
default_icon = gtk_icon_theme_load_icon (theme,
"gtk-missing-image",
META_MINI_ICON_WIDTH,
0,
NULL);
g_assert (default_icon);
}
return default_icon;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,6 @@
#include <meta/util.h>
#include "menu.h"
#include "core.h"
#include "theme-private.h"
#include "inlinepixbufs.h"
@ -367,32 +366,12 @@ meta_ui_get_frame_borders (MetaUI *ui,
Window xwindow,
MetaFrameBorders *borders)
{
MetaFrameFlags flags;
MetaUIFrame *frame;
MetaFrameType type;
frame = meta_ui_lookup_window (ui, xwindow);
MetaUIFrame *frame = meta_ui_lookup_window (ui, xwindow);
if (frame == NULL)
meta_bug ("No such frame 0x%lx\n", xwindow);
meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_FRAME_TYPE, &type,
META_CORE_GET_END);
g_return_if_fail (type < META_FRAME_TYPE_LAST);
/* 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 (frame->tv->theme,
frame->tv->style_context,
type,
flags,
borders);
meta_uiframe_get_frame_borders (frame, borders);
}
void
@ -400,18 +379,8 @@ meta_ui_render_background (MetaUI *ui,
Window xwindow,
cairo_t *cr)
{
MetaUIFrame *frame;
MetaFrameGeometry fgeom;
MetaFrameFlags flags;
frame = meta_ui_lookup_window (ui, xwindow);
meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_END);
meta_uiframe_calc_geometry (frame, &fgeom);
meta_theme_render_background (frame->tv->style_context, cr, flags, &fgeom);
MetaUIFrame *frame = meta_ui_lookup_window (ui, xwindow);
meta_uiframe_paint (frame, cr);
}
Window
@ -589,15 +558,6 @@ meta_ui_unmap_frame (MetaUI *ui,
gdk_window_hide (window);
}
void
meta_ui_update_frame_style (MetaUI *ui,
Window xwindow)
{
MetaUIFrame *frame = meta_ui_lookup_window (ui, xwindow);
meta_uiframe_attach_style (frame);
gtk_widget_queue_draw (GTK_WIDGET (frame));
}
void
meta_ui_queue_frame_draw (MetaUI *ui,
Window xwindow)
@ -825,20 +785,6 @@ meta_text_property_to_utf8 (Display *xdisplay,
return retval;
}
void
meta_ui_set_current_theme (const char *name,
gboolean force_reload)
{
meta_theme_set_current (name, force_reload);
meta_invalidate_default_icons ();
}
gboolean
meta_ui_have_a_theme (void)
{
return meta_theme_get_current () != NULL;
}
static void
meta_ui_accelerator_parse (const char *accel,
guint *keysym,

View File

@ -97,12 +97,6 @@ void meta_ui_set_frame_title (MetaUI *ui,
Window xwindow,
const char *title);
void meta_ui_update_frame_style (MetaUI *ui,
Window window);
void meta_ui_repaint_frame (MetaUI *ui,
Window xwindow);
MetaWindowMenu* meta_ui_window_menu_new (MetaUI *ui,
Display *display,
gint screen_no,
@ -137,10 +131,6 @@ gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay,
char* meta_text_property_to_utf8 (Display *xdisplay,
const XTextProperty *prop);
void meta_ui_set_current_theme (const char *name,
gboolean force_reload);
gboolean meta_ui_have_a_theme (void);
/* Not a real key symbol but means "key above the tab key"; this is
* used as the default keybinding for cycle_group.
* 0x2xxxxxxx is a range not used by GDK or X. the remaining digits are

View File

@ -31,27 +31,139 @@
#include <meta/util.h>
#include "core.h"
#include "menu.h"
#include <meta/theme.h>
#include <meta/prefs.h>
#include "ui.h"
#include "theme-private.h"
#ifdef HAVE_SHAPE
#include <X11/extensions/shape.h>
#endif
static void meta_uiframe_update_prelit_control (MetaUIFrame *frame,
MetaFrameControl control);
static GdkRectangle* control_rect (MetaFrameControl control,
MetaFrameGeometry *fgeom);
static MetaFrameControl get_control (MetaUIFrame *frame,
int x,
int y);
G_DEFINE_TYPE (MetaUIFrame, meta_uiframe, GTK_TYPE_WINDOW);
static void
initialize_style_context (MetaUIFrame *frame)
{
GtkWidget *widget;
GtkCssProvider *provider;
GdkScreen *screen;
char *theme_name, *variant;
if (G_LIKELY (frame->style_context_initialized))
return;
widget = GTK_WIDGET (frame);
screen = gtk_widget_get_screen (widget);
g_object_get (gtk_settings_get_for_screen (screen),
"gtk-theme-name", &theme_name,
NULL);
meta_core_get (GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (frame))),
frame->xwindow,
META_CORE_GET_THEME_VARIANT, &variant,
META_CORE_GET_END);
provider = gtk_css_provider_get_named (theme_name, variant);
gtk_style_context_add_provider (gtk_widget_get_style_context (widget),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_THEME);
g_free (theme_name);
frame->style_context_initialized = TRUE;
}
static void
sync_state_flags (MetaUIFrame *frame)
{
MetaFrameFlags flags;
GtkStateFlags gtk_flags;
initialize_style_context (frame);
meta_core_get (GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (frame))),
frame->xwindow,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_END);
gtk_flags = GTK_STATE_FLAG_NORMAL;
if ((flags & META_FRAME_HAS_FOCUS) == 0)
gtk_flags |= GTK_STATE_FLAG_BACKDROP;
gtk_widget_set_state_flags (GTK_WIDGET (frame), gtk_flags, TRUE);
}
void
meta_uiframe_get_frame_borders (MetaUIFrame *frame,
MetaFrameBorders *borders)
{
GtkWidget *widget = GTK_WIDGET (frame);
GtkBorder padding;
GtkStyleContext *style_context;
MetaFrameType type;
MetaFrameFlags flags;
int draggable_borders;
meta_core_get (GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (frame))),
frame->xwindow,
META_CORE_GET_FRAME_TYPE, &type,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_END);
/* For a full-screen window, we don't have any borders, visible or not. */
if (flags & META_FRAME_FULLSCREEN)
return;
sync_state_flags (frame);
meta_frame_borders_clear (borders);
style_context = gtk_widget_get_style_context (widget);
gtk_style_context_get_border (style_context,
gtk_widget_get_state_flags (widget),
&borders->visible);
gtk_style_context_get_padding (style_context,
gtk_widget_get_state_flags (widget),
&padding);
borders->visible.left += padding.left;
borders->visible.right += padding.right;
borders->visible.top += padding.top;
borders->visible.bottom += padding.bottom;
draggable_borders = meta_prefs_get_draggable_border_width ();
if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE)
{
borders->invisible.left = MAX (0, draggable_borders - borders->visible.left);
borders->invisible.right = MAX (0, draggable_borders - borders->visible.right);
}
if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE)
{
borders->invisible.bottom = MAX (0, 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 (0, 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;
}
static void
meta_uiframe_finalize (GObject *obj)
{
@ -68,6 +180,7 @@ meta_uiframe_init (MetaUIFrame *frame)
frame->container = container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
frame->label = label = gtk_label_new ("");
frame->style_context_initialized = FALSE;
gtk_container_add (GTK_CONTAINER (frame), container);
gtk_container_add (GTK_CONTAINER (container), frame->label);
@ -80,66 +193,19 @@ meta_uiframe_init (MetaUIFrame *frame)
gtk_widget_show_all (GTK_WIDGET (container));
}
/* 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.
*/
void
meta_uiframe_attach_style (MetaUIFrame *frame)
{
char *variant = NULL;
meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
frame->xwindow,
META_CORE_GET_THEME_VARIANT, &variant,
META_CORE_GET_END);
frame->tv = meta_theme_get_variant (meta_theme_get_current (),
variant);
}
void
meta_uiframe_calc_geometry (MetaUIFrame *frame,
MetaFrameGeometry *fgeom)
{
int width, height;
MetaFrameFlags flags;
MetaFrameType type;
MetaButtonLayout button_layout;
meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow,
META_CORE_GET_CLIENT_WIDTH, &width,
META_CORE_GET_CLIENT_HEIGHT, &height,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_FRAME_TYPE, &type,
META_CORE_GET_END);
meta_prefs_get_button_layout (&button_layout);
meta_theme_calc_geometry (frame->tv->theme,
frame->tv->style_context,
type,
flags,
width, height,
&button_layout,
fgeom);
}
/* The client rectangle surrounds client window; it subtracts both
* the visible and invisible borders from the frame window's size.
*/
static void
get_client_rect (MetaFrameGeometry *fgeom,
get_client_rect (MetaFrameBorders *borders,
int window_width,
int window_height,
cairo_rectangle_int_t *rect)
{
rect->x = fgeom->borders.total.left;
rect->y = fgeom->borders.total.top;
rect->width = window_width - fgeom->borders.total.right - rect->x;
rect->height = window_height - fgeom->borders.total.bottom - rect->y;
rect->x = borders->total.left;
rect->y = borders->total.top;
rect->width = window_width - borders->total.right - rect->x;
rect->height = window_height - borders->total.bottom - rect->y;
}
void
@ -149,20 +215,6 @@ meta_uiframe_set_title (MetaUIFrame *frame,
gtk_label_set_text (GTK_LABEL (frame->label), title);
}
static void
redraw_control (MetaUIFrame *frame,
MetaFrameControl control)
{
MetaFrameGeometry fgeom;
GdkRectangle *rect;
meta_uiframe_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,
GdkEventButton *event,
@ -412,35 +464,6 @@ meta_uiframe_button_press_event (GtkWidget *widget,
event->time,
event->x_root,
event->y_root);
frame->prelit_control = control;
redraw_control (frame, control);
if (op == META_GRAB_OP_CLICKING_MENU)
{
MetaFrameGeometry fgeom;
GdkRectangle *rect;
int dx, dy;
meta_uiframe_calc_geometry (frame, &fgeom);
rect = control_rect (META_FRAME_CONTROL_MENU, &fgeom);
/* get delta to convert to root coords */
dx = event->x_root - event->x;
dy = event->y_root - event->y;
/* Align to the right end of the menu rectangle if RTL */
if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
dx += rect->width;
meta_core_show_window_menu (display,
frame->xwindow,
rect->x + dx,
rect->y + rect->height + dy,
event->button,
event->time);
}
}
else if (event->button == 1 &&
(control == META_FRAME_CONTROL_RESIZE_SE ||
@ -644,207 +667,6 @@ meta_uiframe_button_release_event (GtkWidget *widget,
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.
* :)
*/
meta_uiframe_update_prelit_control (frame, control);
}
return TRUE;
}
static void
meta_uiframe_update_prelit_control (MetaUIFrame *frame,
MetaFrameControl control)
{
MetaFrameControl old_control;
MetaCursor cursor;
meta_verbose ("Updating prelit control from %u to %u\n",
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_SHADE:
break;
case META_FRAME_CONTROL_UNSHADE:
break;
case META_FRAME_CONTROL_ABOVE:
break;
case META_FRAME_CONTROL_UNABOVE:
break;
case META_FRAME_CONTROL_STICK:
break;
case META_FRAME_CONTROL_UNSTICK:
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_core_set_screen_cursor (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
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_SHADE:
case META_FRAME_CONTROL_UNSHADE:
case META_FRAME_CONTROL_ABOVE:
case META_FRAME_CONTROL_UNABOVE:
case META_FRAME_CONTROL_STICK:
case META_FRAME_CONTROL_UNSTICK:
case META_FRAME_CONTROL_UNMAXIMIZE:
/* leave control set */
break;
default:
/* Only prelight buttons */
control = META_FRAME_CONTROL_NONE;
break;
}
if (control == frame->prelit_control)
return;
/* Save the old control so we can unprelight it */
old_control = frame->prelit_control;
frame->prelit_control = control;
redraw_control (frame, old_control);
redraw_control (frame, control);
}
static gboolean
meta_uiframe_motion_notify_event (GtkWidget *widget,
GdkEventMotion *event)
{
MetaUIFrame *frame;
MetaGrabOp grab_op;
Display *display;
frame = META_UIFRAME (widget);
display = GDK_DISPLAY_XDISPLAY (gdk_window_get_display (event->window));
grab_op = meta_core_get_grab_op (display);
switch (grab_op)
{
case META_GRAB_OP_CLICKING_MENU:
case META_GRAB_OP_CLICKING_DELETE:
case META_GRAB_OP_CLICKING_MINIMIZE:
case META_GRAB_OP_CLICKING_MAXIMIZE:
case META_GRAB_OP_CLICKING_UNMAXIMIZE:
case META_GRAB_OP_CLICKING_SHADE:
case META_GRAB_OP_CLICKING_UNSHADE:
case META_GRAB_OP_CLICKING_ABOVE:
case META_GRAB_OP_CLICKING_UNABOVE:
case META_GRAB_OP_CLICKING_STICK:
case META_GRAB_OP_CLICKING_UNSTICK:
{
MetaFrameControl control;
int x, y;
gdk_window_get_device_position (frame->window, event->device,
&x, &y, NULL);
/* Control is set to none unless it matches
* the current grab
*/
control = get_control (frame, x, y);
if (! ((control == META_FRAME_CONTROL_MENU &&
grab_op == META_GRAB_OP_CLICKING_MENU) ||
(control == META_FRAME_CONTROL_DELETE &&
grab_op == META_GRAB_OP_CLICKING_DELETE) ||
(control == META_FRAME_CONTROL_MINIMIZE &&
grab_op == META_GRAB_OP_CLICKING_MINIMIZE) ||
((control == META_FRAME_CONTROL_MAXIMIZE ||
control == META_FRAME_CONTROL_UNMAXIMIZE) &&
(grab_op == META_GRAB_OP_CLICKING_MAXIMIZE ||
grab_op == META_GRAB_OP_CLICKING_UNMAXIMIZE)) ||
(control == META_FRAME_CONTROL_SHADE &&
grab_op == META_GRAB_OP_CLICKING_SHADE) ||
(control == META_FRAME_CONTROL_UNSHADE &&
grab_op == META_GRAB_OP_CLICKING_UNSHADE) ||
(control == META_FRAME_CONTROL_ABOVE &&
grab_op == META_GRAB_OP_CLICKING_ABOVE) ||
(control == META_FRAME_CONTROL_UNABOVE &&
grab_op == META_GRAB_OP_CLICKING_UNABOVE) ||
(control == META_FRAME_CONTROL_STICK &&
grab_op == META_GRAB_OP_CLICKING_STICK) ||
(control == META_FRAME_CONTROL_UNSTICK &&
grab_op == META_GRAB_OP_CLICKING_UNSTICK)))
control = META_FRAME_CONTROL_NONE;
/* Update prelit control and cursor */
meta_uiframe_update_prelit_control (frame, control);
}
break;
case META_GRAB_OP_NONE:
{
MetaFrameControl control;
int x, y;
gdk_window_get_device_position (frame->window, event->device,
&x, &y, NULL);
control = get_control (frame, x, y);
/* Update prelit control and cursor */
meta_uiframe_update_prelit_control (frame, control);
}
break;
default:
break;
}
return TRUE;
@ -890,8 +712,6 @@ subtract_client_area (cairo_region_t *region,
MetaUIFrame *frame)
{
cairo_rectangle_int_t area;
MetaFrameFlags flags;
MetaFrameType type;
MetaFrameBorders borders;
cairo_region_t *tmp_region;
Display *display;
@ -899,15 +719,11 @@ subtract_client_area (cairo_region_t *region,
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
meta_core_get (display, frame->xwindow,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_FRAME_TYPE, &type,
META_CORE_GET_CLIENT_WIDTH, &area.width,
META_CORE_GET_CLIENT_HEIGHT, &area.height,
META_CORE_GET_END);
meta_theme_get_frame_borders (frame->tv->theme,
frame->tv->style_context,
type, flags,
&borders);
meta_uiframe_get_frame_borders (frame, &borders);
area.x = borders.total.left;
area.y = borders.total.top;
@ -917,125 +733,41 @@ subtract_client_area (cairo_region_t *region,
cairo_region_destroy (tmp_region);
}
static void
void
meta_uiframe_paint (MetaUIFrame *frame,
cairo_t *cr)
{
MetaFrameFlags flags;
MetaFrameType type;
GdkPixbuf *mini_icon;
GdkPixbuf *icon;
int w, h;
MetaButtonState button_states[META_BUTTON_TYPE_LAST];
Window grab_frame;
int i;
MetaButtonLayout button_layout;
MetaGrabOp grab_op;
Display *display;
GtkWidget *widget = GTK_WIDGET (frame);
GtkStyleContext *style_gtk = gtk_widget_get_style_context (widget);
GdkRectangle visible_rect;
MetaFrameBorders borders;
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
meta_uiframe_get_frame_borders (frame, &borders);
gtk_widget_get_allocation (widget, &visible_rect);
for (i = 0; i < META_BUTTON_TYPE_LAST; i++)
button_states[i] = META_BUTTON_STATE_NORMAL;
visible_rect.x += borders.invisible.left;
visible_rect.y += borders.invisible.top;
visible_rect.width -= borders.invisible.left + borders.invisible.right;
visible_rect.height -= borders.invisible.top - borders.invisible.bottom;
grab_frame = meta_core_get_grab_frame (display);
grab_op = meta_core_get_grab_op (display);
if (grab_frame != frame->xwindow)
grab_op = META_GRAB_OP_NONE;
sync_state_flags (frame);
/* Set prelight state */
switch (frame->prelit_control)
{
case META_FRAME_CONTROL_MENU:
if (grab_op == META_GRAB_OP_CLICKING_MENU)
button_states[META_BUTTON_TYPE_MENU] = META_BUTTON_STATE_PRESSED;
else
button_states[META_BUTTON_TYPE_MENU] = META_BUTTON_STATE_PRELIGHT;
break;
case META_FRAME_CONTROL_MINIMIZE:
if (grab_op == META_GRAB_OP_CLICKING_MINIMIZE)
button_states[META_BUTTON_TYPE_MINIMIZE] = META_BUTTON_STATE_PRESSED;
else
button_states[META_BUTTON_TYPE_MINIMIZE] = META_BUTTON_STATE_PRELIGHT;
break;
case META_FRAME_CONTROL_MAXIMIZE:
if (grab_op == META_GRAB_OP_CLICKING_MAXIMIZE)
button_states[META_BUTTON_TYPE_MAXIMIZE] = META_BUTTON_STATE_PRESSED;
else
button_states[META_BUTTON_TYPE_MAXIMIZE] = META_BUTTON_STATE_PRELIGHT;
break;
case META_FRAME_CONTROL_UNMAXIMIZE:
if (grab_op == META_GRAB_OP_CLICKING_UNMAXIMIZE)
button_states[META_BUTTON_TYPE_MAXIMIZE] = META_BUTTON_STATE_PRESSED;
else
button_states[META_BUTTON_TYPE_MAXIMIZE] = META_BUTTON_STATE_PRELIGHT;
break;
case META_FRAME_CONTROL_SHADE:
if (grab_op == META_GRAB_OP_CLICKING_SHADE)
button_states[META_BUTTON_TYPE_SHADE] = META_BUTTON_STATE_PRESSED;
else
button_states[META_BUTTON_TYPE_SHADE] = META_BUTTON_STATE_PRELIGHT;
break;
case META_FRAME_CONTROL_UNSHADE:
if (grab_op == META_GRAB_OP_CLICKING_UNSHADE)
button_states[META_BUTTON_TYPE_UNSHADE] = META_BUTTON_STATE_PRESSED;
else
button_states[META_BUTTON_TYPE_UNSHADE] = META_BUTTON_STATE_PRELIGHT;
break;
case META_FRAME_CONTROL_ABOVE:
if (grab_op == META_GRAB_OP_CLICKING_ABOVE)
button_states[META_BUTTON_TYPE_ABOVE] = META_BUTTON_STATE_PRESSED;
else
button_states[META_BUTTON_TYPE_ABOVE] = META_BUTTON_STATE_PRELIGHT;
break;
case META_FRAME_CONTROL_UNABOVE:
if (grab_op == META_GRAB_OP_CLICKING_UNABOVE)
button_states[META_BUTTON_TYPE_UNABOVE] = META_BUTTON_STATE_PRESSED;
else
button_states[META_BUTTON_TYPE_UNABOVE] = META_BUTTON_STATE_PRELIGHT;
break;
case META_FRAME_CONTROL_STICK:
if (grab_op == META_GRAB_OP_CLICKING_STICK)
button_states[META_BUTTON_TYPE_STICK] = META_BUTTON_STATE_PRESSED;
else
button_states[META_BUTTON_TYPE_STICK] = META_BUTTON_STATE_PRELIGHT;
break;
case META_FRAME_CONTROL_UNSTICK:
if (grab_op == META_GRAB_OP_CLICKING_UNSTICK)
button_states[META_BUTTON_TYPE_UNSTICK] = META_BUTTON_STATE_PRESSED;
else
button_states[META_BUTTON_TYPE_UNSTICK] = META_BUTTON_STATE_PRELIGHT;
break;
case META_FRAME_CONTROL_DELETE:
if (grab_op == META_GRAB_OP_CLICKING_DELETE)
button_states[META_BUTTON_TYPE_CLOSE] = META_BUTTON_STATE_PRESSED;
else
button_states[META_BUTTON_TYPE_CLOSE] = META_BUTTON_STATE_PRELIGHT;
break;
default:
break;
}
gtk_render_background (style_gtk, cr,
visible_rect.x,
visible_rect.y,
visible_rect.width,
visible_rect.height);
meta_core_get (display, frame->xwindow,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_FRAME_TYPE, &type,
META_CORE_GET_MINI_ICON, &mini_icon,
META_CORE_GET_ICON, &icon,
META_CORE_GET_CLIENT_WIDTH, &w,
META_CORE_GET_CLIENT_HEIGHT, &h,
META_CORE_GET_END);
gtk_render_frame (style_gtk, cr,
visible_rect.x,
visible_rect.y,
visible_rect.width,
visible_rect.height);
meta_prefs_get_button_layout (&button_layout);
meta_theme_draw_frame_with_style (frame->tv->theme,
frame->tv->style_context,
cr,
type,
flags,
w, h,
&button_layout,
button_states,
mini_icon, icon);
/* We chain up to paint the contents here so that the mask
* we paint with meta_frame_render_background can be accurate
* with children. */
GTK_WIDGET_CLASS (meta_uiframe_parent_class)->draw (widget, cr);
}
static gboolean
@ -1068,8 +800,6 @@ meta_uiframe_draw (GtkWidget *widget,
meta_uiframe_paint (frame, cr);
GTK_WIDGET_CLASS (meta_uiframe_parent_class)->draw (widget, cr);
out:
cairo_region_destroy (region);
@ -1081,199 +811,52 @@ meta_uiframe_style_updated (GtkWidget *widget)
{
MetaUIFrame *frame = META_UIFRAME (widget);
GtkWidget *container = frame->container;
MetaFrameGeometry fgeom;
MetaFrameBorders borders;
meta_uiframe_calc_geometry (frame, &fgeom);
meta_uiframe_get_frame_borders (frame, &borders);
gtk_widget_set_margin_left (container, fgeom.borders.total.left);
gtk_widget_set_margin_right (container, fgeom.borders.total.right);
gtk_widget_set_margin_top (container, fgeom.borders.invisible.top);
gtk_widget_set_size_request (container, -1, fgeom.borders.visible.top);
gtk_widget_set_margin_left (container, borders.total.left);
gtk_widget_set_margin_right (container, borders.total.right);
gtk_widget_set_margin_top (container, borders.invisible.top);
gtk_widget_set_size_request (container, -1, borders.visible.top);
}
static gboolean
meta_uiframe_enter_notify_event (GtkWidget *widget,
GdkEventCrossing *event)
{
MetaUIFrame *frame;
MetaFrameControl control;
frame = META_UIFRAME (widget);
control = get_control (frame, event->x, event->y);
meta_uiframe_update_prelit_control (frame, control);
return TRUE;
}
static gboolean
meta_uiframe_leave_notify_event (GtkWidget *widget,
GdkEventCrossing *event)
{
MetaUIFrame *frame = META_UIFRAME (widget);
meta_uiframe_update_prelit_control (frame, META_FRAME_CONTROL_NONE);
return TRUE;
}
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_SHADE:
rect = &fgeom->shade_rect.visible;
break;
case META_FRAME_CONTROL_UNSHADE:
rect = &fgeom->unshade_rect.visible;
break;
case META_FRAME_CONTROL_ABOVE:
rect = &fgeom->above_rect.visible;
break;
case META_FRAME_CONTROL_UNABOVE:
rect = &fgeom->unabove_rect.visible;
break;
case META_FRAME_CONTROL_STICK:
rect = &fgeom->stick_rect.visible;
break;
case META_FRAME_CONTROL_UNSTICK:
rect = &fgeom->unstick_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
static MetaFrameControl
get_control (MetaUIFrame *frame,
int x, int y)
{
MetaFrameGeometry fgeom;
MetaFrameBorders borders;
MetaFrameFlags flags;
MetaFrameType type;
gboolean has_vert, has_horiz;
gboolean has_north_resize;
cairo_rectangle_int_t client;
meta_uiframe_calc_geometry (frame, &fgeom);
get_client_rect (&fgeom, fgeom.width, fgeom.height, &client);
if (POINT_IN_RECT (x, y, client))
return META_FRAME_CONTROL_CLIENT_AREA;
if (POINT_IN_RECT (x, y, fgeom.close_rect.clickable))
return META_FRAME_CONTROL_DELETE;
if (POINT_IN_RECT (x, y, fgeom.min_rect.clickable))
return META_FRAME_CONTROL_MINIMIZE;
if (POINT_IN_RECT (x, y, fgeom.menu_rect.clickable))
return META_FRAME_CONTROL_MENU;
int width, height;
meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
frame->xwindow,
META_CORE_GET_FRAME_FLAGS, &flags,
META_CORE_GET_CLIENT_WIDTH, &width,
META_CORE_GET_CLIENT_HEIGHT, &height,
META_CORE_GET_FRAME_TYPE, &type,
META_CORE_GET_END);
meta_uiframe_get_frame_borders (frame, &borders);
get_client_rect (&borders, width, height, &client);
if (POINT_IN_RECT (x, y, client))
return META_FRAME_CONTROL_CLIENT_AREA;
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 (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 (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;
}
if (POINT_IN_RECT (x, y, fgeom.shade_rect.clickable))
{
return META_FRAME_CONTROL_SHADE;
}
if (POINT_IN_RECT (x, y, fgeom.unshade_rect.clickable))
{
return META_FRAME_CONTROL_UNSHADE;
}
if (POINT_IN_RECT (x, y, fgeom.above_rect.clickable))
{
return META_FRAME_CONTROL_ABOVE;
}
if (POINT_IN_RECT (x, y, fgeom.unabove_rect.clickable))
{
return META_FRAME_CONTROL_UNABOVE;
}
if (POINT_IN_RECT (x, y, fgeom.stick_rect.clickable))
{
return META_FRAME_CONTROL_STICK;
}
if (POINT_IN_RECT (x, y, fgeom.unstick_rect.clickable))
{
return META_FRAME_CONTROL_UNSTICK;
}
/* South resize always has priority over north resize,
* in case of overlap.
*/
if (y >= (fgeom.height - fgeom.borders.total.bottom) &&
x >= (fgeom.width - fgeom.borders.total.right))
if (y >= (height - borders.total.bottom) &&
x >= (width - borders.total.right))
{
if (has_vert && has_horiz)
return META_FRAME_CONTROL_RESIZE_SE;
@ -1282,8 +865,8 @@ get_control (MetaUIFrame *frame,
else if (has_horiz)
return META_FRAME_CONTROL_RESIZE_E;
}
else if (y >= (fgeom.height - fgeom.borders.total.bottom) &&
x <= fgeom.borders.total.left)
else if (y >= (height - borders.total.bottom) &&
x <= borders.total.left)
{
if (has_vert && has_horiz)
return META_FRAME_CONTROL_RESIZE_SW;
@ -1292,8 +875,8 @@ get_control (MetaUIFrame *frame,
else if (has_horiz)
return META_FRAME_CONTROL_RESIZE_W;
}
else if (y < (fgeom.borders.invisible.top) &&
x <= fgeom.borders.total.left && has_north_resize)
else if (y < (borders.invisible.top) &&
x <= borders.total.left && has_north_resize)
{
if (has_vert && has_horiz)
return META_FRAME_CONTROL_RESIZE_NW;
@ -1302,8 +885,8 @@ get_control (MetaUIFrame *frame,
else if (has_horiz)
return META_FRAME_CONTROL_RESIZE_W;
}
else if (y < (fgeom.borders.invisible.top) &&
x >= fgeom.width - fgeom.borders.total.right && has_north_resize)
else if (y < (borders.invisible.top) &&
x >= width - borders.total.right && has_north_resize)
{
if (has_vert && has_horiz)
return META_FRAME_CONTROL_RESIZE_NE;
@ -1312,28 +895,28 @@ get_control (MetaUIFrame *frame,
else if (has_horiz)
return META_FRAME_CONTROL_RESIZE_E;
}
else if (y < (fgeom.borders.invisible.top + TOP_RESIZE_HEIGHT))
else if (y < borders.invisible.top)
{
if (has_vert && has_north_resize)
return META_FRAME_CONTROL_RESIZE_N;
}
else if (y >= (fgeom.height - fgeom.borders.total.bottom))
else if (y >= (height - borders.total.bottom))
{
if (has_vert)
return META_FRAME_CONTROL_RESIZE_S;
}
else if (x <= fgeom.borders.total.left)
else if (x <= borders.total.left)
{
if (has_horiz)
return META_FRAME_CONTROL_RESIZE_W;
}
else if (x >= (fgeom.width - fgeom.borders.total.right))
else if (x >= (width - borders.total.right))
{
if (has_horiz)
return META_FRAME_CONTROL_RESIZE_E;
}
if (y >= fgeom.borders.total.top)
if (y >= borders.total.top)
return META_FRAME_CONTROL_NONE;
else
return META_FRAME_CONTROL_TITLE;
@ -1354,7 +937,4 @@ meta_uiframe_class_init (MetaUIFrameClass *class)
widget_class->style_updated = meta_uiframe_style_updated;
widget_class->button_press_event = meta_uiframe_button_press_event;
widget_class->button_release_event = meta_uiframe_button_release_event;
widget_class->motion_notify_event = meta_uiframe_motion_notify_event;
widget_class->enter_notify_event = meta_uiframe_enter_notify_event;
widget_class->leave_notify_event = meta_uiframe_leave_notify_event;
}

View File

@ -27,7 +27,6 @@
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <meta/common.h>
#include "theme-private.h"
typedef enum
{
@ -75,11 +74,12 @@ struct _MetaUIFrame
Window xwindow;
GdkWindow *window;
MetaThemeVariant *tv;
MetaFrameControl prelit_control;
GtkWidget *label;
GtkWidget *container;
gboolean style_context_initialized;
};
struct _MetaUIFrameClass
@ -92,9 +92,10 @@ GType meta_uiframe_get_type (void) G_GNUC_CONST;
void meta_uiframe_set_title (MetaUIFrame *frame,
const char *title);
void meta_uiframe_attach_style (MetaUIFrame *frame);
void meta_uiframe_paint (MetaUIFrame *frame,
cairo_t *cr);
void meta_uiframe_calc_geometry (MetaUIFrame *frame,
MetaFrameGeometry *fgeom);
void meta_uiframe_get_frame_borders (MetaUIFrame *frame,
MetaFrameBorders *borders);
#endif