mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
use gtk+ theme impl
This commit is contained in:
parent
9c362f7fe4
commit
2ff2a27229
@ -102,8 +102,6 @@ libmutter_la_SOURCES = \
|
||||
meta/errors.h \
|
||||
core/frame.c \
|
||||
core/frame.h \
|
||||
ui/gradient.c \
|
||||
meta/gradient.h \
|
||||
core/group-private.h \
|
||||
core/group-props.c \
|
||||
core/group-props.h \
|
||||
@ -152,20 +150,12 @@ libmutter_la_SOURCES = \
|
||||
core/xprops.h \
|
||||
meta/common.h \
|
||||
core/core.h \
|
||||
ui/ui.c \
|
||||
ui/ui.h \
|
||||
ui/frames.c \
|
||||
ui/frames.h \
|
||||
ui/menu.c \
|
||||
ui/menu.h \
|
||||
ui/metaaccellabel.c \
|
||||
ui/metaaccellabel.h \
|
||||
ui/resizepopup.c \
|
||||
ui/resizepopup.h \
|
||||
ui/theme-parser.c \
|
||||
ui/theme.c \
|
||||
meta/theme.h \
|
||||
ui/theme-private.h \
|
||||
ui/ui.c
|
||||
ui/resizepopup.h
|
||||
|
||||
nodist_libmutter_la_SOURCES = \
|
||||
$(mutter_built_sources)
|
||||
@ -183,7 +173,6 @@ libmutterinclude_base_headers = \
|
||||
meta/compositor.h \
|
||||
meta/display.h \
|
||||
meta/errors.h \
|
||||
meta/gradient.h \
|
||||
meta/group.h \
|
||||
meta/keybindings.h \
|
||||
meta/main.h \
|
||||
@ -198,7 +187,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 \
|
||||
@ -254,13 +242,11 @@ Meta-$(api_version).gir: libmutter.la
|
||||
endif
|
||||
|
||||
testboxes_SOURCES = core/testboxes.c
|
||||
testgradient_SOURCES = ui/testgradient.c
|
||||
testasyncgetprop_SOURCES = core/testasyncgetprop.c
|
||||
|
||||
noinst_PROGRAMS=testboxes testgradient testasyncgetprop
|
||||
noinst_PROGRAMS=testboxes testasyncgetprop
|
||||
|
||||
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
testgradient_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
@ -361,6 +361,7 @@ meta_window_actor_dispose (GObject *object)
|
||||
xdisplay = meta_display_get_xdisplay (display);
|
||||
info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
meta_window_actor_set_redirected (self, FALSE);
|
||||
meta_window_actor_detach (self);
|
||||
|
||||
if (priv->send_frame_messages_timer != 0)
|
||||
@ -484,6 +485,36 @@ meta_window_actor_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static 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>";
|
||||
}
|
||||
|
||||
static const char *
|
||||
meta_window_actor_get_shadow_class (MetaWindowActor *self)
|
||||
{
|
||||
@ -1842,43 +1873,6 @@ meta_window_actor_sync_visibility (MetaWindowActor *self)
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
scan_visible_region (guchar *mask_data,
|
||||
int stride,
|
||||
cairo_region_t *scan_area)
|
||||
{
|
||||
int i, n_rects = cairo_region_num_rectangles (scan_area);
|
||||
MetaRegionBuilder builder;
|
||||
|
||||
meta_region_builder_init (&builder);
|
||||
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
int x, y;
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_rectangle (scan_area, i, &rect);
|
||||
|
||||
for (y = rect.y; y < (rect.y + rect.height); y++)
|
||||
{
|
||||
for (x = rect.x; x < (rect.x + rect.width); x++)
|
||||
{
|
||||
int x2 = x;
|
||||
while (mask_data[y * stride + x2] == 255 && x2 < (rect.x + rect.width))
|
||||
x2++;
|
||||
|
||||
if (x2 > x)
|
||||
{
|
||||
meta_region_builder_add_rectangle (&builder, x, y, x2 - x, 1);
|
||||
x = x2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return meta_region_builder_finish (&builder);
|
||||
}
|
||||
|
||||
static void
|
||||
build_and_scan_frame_mask (MetaWindowActor *self,
|
||||
cairo_rectangle_int_t *client_area,
|
||||
@ -1914,27 +1908,6 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
||||
gdk_cairo_region (cr, shape_region);
|
||||
cairo_fill (cr);
|
||||
|
||||
if (priv->window->frame != NULL)
|
||||
{
|
||||
cairo_region_t *frame_paint_region, *scanned_region;
|
||||
cairo_rectangle_int_t rect = { 0, 0, tex_width, tex_height };
|
||||
|
||||
/* Make sure we don't paint the frame over the client window. */
|
||||
frame_paint_region = cairo_region_create_rectangle (&rect);
|
||||
cairo_region_subtract_rectangle (frame_paint_region, client_area);
|
||||
|
||||
gdk_cairo_region (cr, frame_paint_region);
|
||||
cairo_clip (cr);
|
||||
|
||||
meta_frame_get_mask (priv->window->frame, cr);
|
||||
|
||||
cairo_surface_flush (surface);
|
||||
scanned_region = scan_visible_region (mask_data, stride, frame_paint_region);
|
||||
cairo_region_union (shape_region, scanned_region);
|
||||
cairo_region_destroy (scanned_region);
|
||||
cairo_region_destroy (frame_paint_region);
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
|
159
src/core/frame.c
159
src/core/frame.c
@ -43,7 +43,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
{
|
||||
MetaFrame *frame;
|
||||
XSetWindowAttributes attrs;
|
||||
Visual *visual;
|
||||
gulong create_serial;
|
||||
|
||||
if (window->frame)
|
||||
@ -62,53 +61,34 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
frame->current_cursor = 0;
|
||||
|
||||
frame->is_flashing = FALSE;
|
||||
frame->borders_cached = FALSE;
|
||||
|
||||
meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
|
||||
window->desc,
|
||||
XVisualIDFromVisual (window->xvisual) ==
|
||||
XVisualIDFromVisual (window->screen->default_xvisual) ?
|
||||
"is" : "is not",
|
||||
window->depth, window->screen->default_depth);
|
||||
|
||||
meta_verbose ("Frame geometry %d,%d %dx%d\n",
|
||||
frame->rect.x, frame->rect.y,
|
||||
frame->rect.width, frame->rect.height);
|
||||
|
||||
/* 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. NULL means default visual.
|
||||
*
|
||||
* We look for an ARGB visual if we can find one, otherwise use
|
||||
* the default of NULL.
|
||||
*/
|
||||
|
||||
/* Special case for depth 32 windows (assumed to be ARGB),
|
||||
* we use the window's visual. Otherwise we just use the system visual.
|
||||
*/
|
||||
if (window->depth == 32)
|
||||
visual = window->xvisual;
|
||||
else
|
||||
visual = NULL;
|
||||
|
||||
frame->xwindow = meta_ui_create_frame_window (window->screen->ui,
|
||||
window->display->xdisplay,
|
||||
visual,
|
||||
frame->rect.x,
|
||||
frame->rect.y,
|
||||
frame->rect.width,
|
||||
frame->rect.height,
|
||||
frame->window->screen->number,
|
||||
&create_serial);
|
||||
|
||||
attrs.event_mask = EVENT_MASK;
|
||||
XChangeWindowAttributes (window->display->xdisplay,
|
||||
frame->xwindow, CWEventMask, &attrs);
|
||||
|
||||
create_serial = XNextRequest (window->display->xdisplay);
|
||||
|
||||
frame->xwindow = XCreateWindow (window->display->xdisplay,
|
||||
DefaultRootWindow (window->display->xdisplay),
|
||||
frame->rect.x, frame->rect.y,
|
||||
frame->rect.width, frame->rect.height,
|
||||
0,
|
||||
CopyFromParent,
|
||||
InputOnly,
|
||||
CopyFromParent,
|
||||
CWEventMask,
|
||||
&attrs);
|
||||
|
||||
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
||||
frame->xwindow,
|
||||
create_serial);
|
||||
|
||||
meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow);
|
||||
attrs.event_mask = EVENT_MASK;
|
||||
XChangeWindowAttributes (window->display->xdisplay,
|
||||
frame->xwindow, CWEventMask, &attrs);
|
||||
|
||||
|
||||
meta_display_register_x_window (window->display, &frame->xwindow, window);
|
||||
|
||||
meta_error_trap_push (window->display);
|
||||
@ -128,28 +108,12 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
meta_stack_tracker_record_remove (window->screen->stack_tracker,
|
||||
window->xwindow,
|
||||
XNextRequest (window->display->xdisplay));
|
||||
XReparentWindow (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
frame->xwindow,
|
||||
window->rect.x,
|
||||
window->rect.y);
|
||||
/* FIXME handle this error */
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
/* stick frame to the window */
|
||||
window->frame = frame;
|
||||
|
||||
/* 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_reset_frame_bg (window->screen->ui, frame->xwindow);
|
||||
|
||||
if (window->title)
|
||||
meta_ui_set_frame_title (window->screen->ui,
|
||||
window->frame->xwindow,
|
||||
window->title);
|
||||
|
||||
/* Move keybindings to frame instead of window */
|
||||
meta_window_grab_keys (window);
|
||||
|
||||
@ -190,18 +154,9 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
||||
window->xwindow,
|
||||
XNextRequest (window->display->xdisplay));
|
||||
XReparentWindow (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
window->screen->xroot,
|
||||
/* Using anything other than meta_window_get_position()
|
||||
* coordinates here means we'll need to ensure a configure
|
||||
* notify event is sent; see bug 399552.
|
||||
*/
|
||||
window->frame->rect.x + borders.invisible.left,
|
||||
window->frame->rect.y + borders.invisible.top);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
meta_ui_destroy_frame_window (window->screen->ui, frame->xwindow);
|
||||
XDestroyWindow (window->display->xdisplay, frame->xwindow);
|
||||
|
||||
meta_display_unregister_x_window (window->display,
|
||||
frame->xwindow);
|
||||
@ -309,22 +264,7 @@ void
|
||||
meta_frame_calc_borders (MetaFrame *frame,
|
||||
MetaFrameBorders *borders)
|
||||
{
|
||||
/* Save on if statements and potential uninitialized values
|
||||
* in callers -- if there's no frame, then zero the borders. */
|
||||
if (frame == NULL)
|
||||
meta_frame_borders_clear (borders);
|
||||
else
|
||||
{
|
||||
if (!frame->borders_cached)
|
||||
{
|
||||
meta_ui_get_frame_borders (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
&frame->cached_borders);
|
||||
frame->borders_cached = TRUE;
|
||||
}
|
||||
|
||||
*borders = frame->cached_borders;
|
||||
}
|
||||
meta_frame_borders_clear (borders);
|
||||
}
|
||||
|
||||
void
|
||||
@ -346,35 +286,12 @@ meta_frame_sync_to_window (MetaFrame *frame,
|
||||
frame->rect.x + frame->rect.width,
|
||||
frame->rect.y + frame->rect.height);
|
||||
|
||||
/* set bg to none to avoid flicker */
|
||||
if (need_resize)
|
||||
{
|
||||
meta_ui_unflicker_frame_bg (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
frame->rect.width,
|
||||
frame->rect.height);
|
||||
}
|
||||
|
||||
meta_ui_move_resize_frame (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
frame->rect.x,
|
||||
frame->rect.y,
|
||||
frame->rect.width,
|
||||
frame->rect.height);
|
||||
|
||||
if (need_resize)
|
||||
{
|
||||
meta_ui_reset_frame_bg (frame->window->screen->ui,
|
||||
frame->xwindow);
|
||||
|
||||
/* If we're interactively resizing the frame, repaint
|
||||
* it immediately so we don't start to lag.
|
||||
*/
|
||||
if (frame->window->display->grab_window ==
|
||||
frame->window)
|
||||
meta_ui_repaint_frame (frame->window->screen->ui,
|
||||
frame->xwindow);
|
||||
}
|
||||
XMoveResizeWindow (frame->window->display->xdisplay,
|
||||
frame->xwindow,
|
||||
frame->rect.x,
|
||||
frame->rect.y,
|
||||
frame->rect.width,
|
||||
frame->rect.height);
|
||||
|
||||
return need_resize;
|
||||
}
|
||||
@ -382,25 +299,19 @@ meta_frame_sync_to_window (MetaFrame *frame,
|
||||
cairo_region_t *
|
||||
meta_frame_get_frame_bounds (MetaFrame *frame)
|
||||
{
|
||||
return meta_ui_get_frame_bounds (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
frame->rect.width,
|
||||
frame->rect.height);
|
||||
}
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
void
|
||||
meta_frame_get_mask (MetaFrame *frame,
|
||||
cairo_t *cr)
|
||||
{
|
||||
meta_ui_get_frame_mask (frame->window->screen->ui, frame->xwindow,
|
||||
frame->rect.width, frame->rect.height, cr);
|
||||
rect.x = frame->window->rect.x;
|
||||
rect.y = frame->window->rect.y;
|
||||
rect.width = frame->window->rect.width;
|
||||
rect.height = frame->window->rect.height;
|
||||
|
||||
return cairo_region_create_rectangles (&rect, 1);
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_queue_draw (MetaFrame *frame)
|
||||
{
|
||||
meta_ui_queue_frame_draw (frame->window->screen->ui,
|
||||
frame->xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -72,9 +72,6 @@ void meta_frame_clear_cached_borders (MetaFrame *frame);
|
||||
|
||||
cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame);
|
||||
|
||||
void meta_frame_get_mask (MetaFrame *frame,
|
||||
cairo_t *cr);
|
||||
|
||||
void meta_frame_set_screen_cursor (MetaFrame *frame,
|
||||
MetaCursor cursor);
|
||||
|
||||
|
@ -1983,10 +1983,6 @@ meta_display_process_key_event (MetaDisplay *display,
|
||||
if (screen == NULL)
|
||||
return FALSE; /* event window is destroyed */
|
||||
|
||||
/* ignore key events on popup menus and such. */
|
||||
if (meta_ui_window_is_widget (screen->ui, event->event))
|
||||
return FALSE;
|
||||
|
||||
/* window may be NULL */
|
||||
|
||||
keysym = XKeycodeToKeysym (display->xdisplay, event->detail, 0);
|
||||
|
@ -523,42 +523,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 ());
|
||||
|
||||
/* 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");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
if (!meta_display_open ())
|
||||
meta_exit (META_EXIT_ERROR);
|
||||
@ -606,12 +570,6 @@ 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 ());
|
||||
meta_display_retheme_all ();
|
||||
break;
|
||||
|
||||
case META_PREF_CURSOR_THEME:
|
||||
case META_PREF_CURSOR_SIZE:
|
||||
meta_display_set_cursor_theme (meta_prefs_get_cursor_theme (),
|
||||
|
@ -80,7 +80,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;
|
||||
@ -132,7 +131,6 @@ static void queue_changed (MetaPreference pref);
|
||||
static void maybe_give_disable_workarounds_warning (void);
|
||||
|
||||
static gboolean titlebar_handler (GVariant*, gpointer*, gpointer);
|
||||
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);
|
||||
static gboolean overlay_key_handler (GVariant*, gpointer*, gpointer);
|
||||
@ -382,14 +380,6 @@ static MetaStringPreference preferences_string[] =
|
||||
mouse_button_mods_handler,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
{ "theme",
|
||||
SCHEMA_GENERAL,
|
||||
META_PREF_THEME,
|
||||
},
|
||||
theme_name_handler,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
{ KEY_TITLEBAR_FONT,
|
||||
SCHEMA_GENERAL,
|
||||
@ -1225,12 +1215,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)
|
||||
{
|
||||
@ -1287,31 +1271,6 @@ titlebar_handler (GVariant *value,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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,
|
||||
@ -1731,9 +1690,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_TITLEBAR_FONT:
|
||||
return "TITLEBAR_FONT";
|
||||
|
||||
|
@ -711,9 +711,7 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
|
||||
* XID => window table. (Wine uses a toplevel for _NET_WM_USER_TIME_WINDOW;
|
||||
* see window-prop.c:reload_net_wm_user_time_window() for registration.)
|
||||
*/
|
||||
if (meta_window &&
|
||||
(windows[i] == meta_window->xwindow ||
|
||||
(meta_window->frame && windows[i] == meta_window->frame->xwindow)))
|
||||
if (meta_window && windows[i] == meta_window->xwindow)
|
||||
meta_windows = g_list_prepend (meta_windows, meta_window);
|
||||
}
|
||||
|
||||
|
@ -1189,10 +1189,7 @@ stack_sync_to_server (MetaStack *stack)
|
||||
else
|
||||
g_array_prepend_val (stacked, w->xwindow);
|
||||
|
||||
if (w->frame)
|
||||
top_level_window = w->frame->xwindow;
|
||||
else
|
||||
top_level_window = w->xwindow;
|
||||
top_level_window = w->xwindow;
|
||||
|
||||
/* We don't restack hidden windows along with the rest, though they are
|
||||
* reflected in the _NET hints. Hidden windows all get pushed below
|
||||
|
@ -1705,13 +1705,6 @@ meta_window_unmanage (MetaWindow *window,
|
||||
meta_compositor_remove_window (window->display->compositor, window);
|
||||
}
|
||||
|
||||
if (window->display->window_with_menu == window)
|
||||
{
|
||||
meta_ui_window_menu_free (window->display->window_menu);
|
||||
window->display->window_menu = NULL;
|
||||
window->display->window_with_menu = NULL;
|
||||
}
|
||||
|
||||
if (destroying_windows_disallowed > 0)
|
||||
meta_bug ("Tried to destroy window %s while destruction was not allowed\n",
|
||||
window->desc);
|
||||
@ -3697,10 +3690,6 @@ meta_window_tile (MetaWindow *window)
|
||||
window,
|
||||
&old_rect,
|
||||
&new_rect);
|
||||
|
||||
if (window->frame)
|
||||
meta_ui_queue_frame_draw (window->screen->ui,
|
||||
window->frame->xwindow);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -7888,11 +7877,6 @@ meta_window_update_shape_region_x11 (MetaWindow *window)
|
||||
static void
|
||||
redraw_icon (MetaWindow *window)
|
||||
{
|
||||
/* We could probably be smart and just redraw the icon here,
|
||||
* instead of the whole frame.
|
||||
*/
|
||||
if (window->frame)
|
||||
meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
@ -8644,145 +8628,6 @@ recalc_window_features (MetaWindow *window)
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
menu_callback (MetaWindowMenu *menu,
|
||||
Display *xdisplay,
|
||||
Window client_xwindow,
|
||||
guint32 timestamp,
|
||||
MetaMenuOp op,
|
||||
int workspace_index,
|
||||
gpointer data)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaWindow *window;
|
||||
MetaWorkspace *workspace;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
window = meta_display_lookup_x_window (display, client_xwindow);
|
||||
workspace = NULL;
|
||||
|
||||
if (window != NULL) /* window can be NULL */
|
||||
{
|
||||
meta_verbose ("Menu op %u on %s\n", op, window->desc);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case META_MENU_OP_NONE:
|
||||
/* nothing */
|
||||
break;
|
||||
|
||||
case META_MENU_OP_DELETE:
|
||||
meta_window_delete (window, timestamp);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_MINIMIZE:
|
||||
meta_window_minimize (window);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_UNMAXIMIZE:
|
||||
meta_window_unmaximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL |
|
||||
META_MAXIMIZE_VERTICAL);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_MAXIMIZE:
|
||||
meta_window_maximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL |
|
||||
META_MAXIMIZE_VERTICAL);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_UNSHADE:
|
||||
meta_window_unshade (window, timestamp);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_SHADE:
|
||||
meta_window_shade (window, timestamp);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_MOVE_LEFT:
|
||||
workspace = meta_workspace_get_neighbor (window->screen->active_workspace,
|
||||
META_MOTION_LEFT);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_MOVE_RIGHT:
|
||||
workspace = meta_workspace_get_neighbor (window->screen->active_workspace,
|
||||
META_MOTION_RIGHT);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_MOVE_UP:
|
||||
workspace = meta_workspace_get_neighbor (window->screen->active_workspace,
|
||||
META_MOTION_UP);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_MOVE_DOWN:
|
||||
workspace = meta_workspace_get_neighbor (window->screen->active_workspace,
|
||||
META_MOTION_DOWN);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_WORKSPACES:
|
||||
workspace = meta_screen_get_workspace_by_index (window->screen,
|
||||
workspace_index);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_STICK:
|
||||
meta_window_stick (window);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_UNSTICK:
|
||||
meta_window_unstick (window);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_ABOVE:
|
||||
case META_MENU_OP_UNABOVE:
|
||||
if (window->wm_state_above == FALSE)
|
||||
meta_window_make_above (window);
|
||||
else
|
||||
meta_window_unmake_above (window);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_MOVE:
|
||||
meta_window_begin_grab_op (window,
|
||||
META_GRAB_OP_KEYBOARD_MOVING,
|
||||
TRUE,
|
||||
timestamp);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_RESIZE:
|
||||
meta_window_begin_grab_op (window,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
|
||||
TRUE,
|
||||
timestamp);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_RECOVER:
|
||||
meta_window_shove_titlebar_onscreen (window);
|
||||
break;
|
||||
|
||||
default:
|
||||
meta_warning (G_STRLOC": Unknown window op\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (workspace)
|
||||
{
|
||||
meta_window_change_workspace (window,
|
||||
workspace);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_verbose ("Menu callback on nonexistent window\n");
|
||||
}
|
||||
|
||||
if (display->window_menu == menu)
|
||||
{
|
||||
display->window_menu = NULL;
|
||||
display->window_with_menu = NULL;
|
||||
}
|
||||
|
||||
meta_ui_window_menu_free (menu);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_show_menu (MetaWindow *window,
|
||||
int root_x,
|
||||
@ -8790,126 +8635,6 @@ meta_window_show_menu (MetaWindow *window,
|
||||
int button,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaMenuOp ops;
|
||||
MetaMenuOp insensitive;
|
||||
MetaWindowMenu *menu;
|
||||
MetaWorkspaceLayout layout;
|
||||
int n_workspaces;
|
||||
gboolean ltr;
|
||||
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
if (window->display->window_menu)
|
||||
{
|
||||
meta_ui_window_menu_free (window->display->window_menu);
|
||||
window->display->window_menu = NULL;
|
||||
window->display->window_with_menu = NULL;
|
||||
}
|
||||
|
||||
ops = META_MENU_OP_NONE;
|
||||
insensitive = META_MENU_OP_NONE;
|
||||
|
||||
ops |= (META_MENU_OP_DELETE | META_MENU_OP_MINIMIZE | META_MENU_OP_MOVE | META_MENU_OP_RESIZE);
|
||||
|
||||
if (!meta_window_titlebar_is_onscreen (window) &&
|
||||
window->type != META_WINDOW_DOCK &&
|
||||
window->type != META_WINDOW_DESKTOP)
|
||||
ops |= META_MENU_OP_RECOVER;
|
||||
|
||||
if (!meta_prefs_get_workspaces_only_on_primary () ||
|
||||
meta_window_is_on_primary_monitor (window))
|
||||
{
|
||||
n_workspaces = meta_screen_get_n_workspaces (window->screen);
|
||||
|
||||
if (n_workspaces > 1)
|
||||
ops |= META_MENU_OP_WORKSPACES;
|
||||
|
||||
meta_screen_calc_workspace_layout (window->screen,
|
||||
n_workspaces,
|
||||
meta_workspace_index ( window->screen->active_workspace),
|
||||
&layout);
|
||||
|
||||
if (!window->on_all_workspaces)
|
||||
{
|
||||
ltr = meta_ui_get_direction() == META_UI_DIRECTION_LTR;
|
||||
|
||||
if (layout.current_col > 0)
|
||||
ops |= ltr ? META_MENU_OP_MOVE_LEFT : META_MENU_OP_MOVE_RIGHT;
|
||||
if ((layout.current_col < layout.cols - 1) &&
|
||||
(layout.current_row * layout.cols + (layout.current_col + 1) < n_workspaces))
|
||||
ops |= ltr ? META_MENU_OP_MOVE_RIGHT : META_MENU_OP_MOVE_LEFT;
|
||||
if (layout.current_row > 0)
|
||||
ops |= META_MENU_OP_MOVE_UP;
|
||||
if ((layout.current_row < layout.rows - 1) &&
|
||||
((layout.current_row + 1) * layout.cols + layout.current_col < n_workspaces))
|
||||
ops |= META_MENU_OP_MOVE_DOWN;
|
||||
}
|
||||
|
||||
meta_screen_free_workspace_layout (&layout);
|
||||
|
||||
ops |= META_MENU_OP_UNSTICK;
|
||||
ops |= META_MENU_OP_STICK;
|
||||
}
|
||||
|
||||
if (META_WINDOW_MAXIMIZED (window))
|
||||
ops |= META_MENU_OP_UNMAXIMIZE;
|
||||
else
|
||||
ops |= META_MENU_OP_MAXIMIZE;
|
||||
|
||||
if (window->wm_state_above)
|
||||
ops |= META_MENU_OP_UNABOVE;
|
||||
else
|
||||
ops |= META_MENU_OP_ABOVE;
|
||||
|
||||
if (!window->has_maximize_func)
|
||||
insensitive |= META_MENU_OP_UNMAXIMIZE | META_MENU_OP_MAXIMIZE;
|
||||
|
||||
if (!window->has_minimize_func)
|
||||
insensitive |= META_MENU_OP_MINIMIZE;
|
||||
|
||||
if (!window->has_close_func)
|
||||
insensitive |= META_MENU_OP_DELETE;
|
||||
|
||||
if (!window->has_shade_func)
|
||||
insensitive |= META_MENU_OP_SHADE | META_MENU_OP_UNSHADE;
|
||||
|
||||
if (!META_WINDOW_ALLOWS_MOVE (window))
|
||||
insensitive |= META_MENU_OP_MOVE;
|
||||
|
||||
if (!META_WINDOW_ALLOWS_RESIZE (window))
|
||||
insensitive |= META_MENU_OP_RESIZE;
|
||||
|
||||
if (window->always_sticky)
|
||||
insensitive |= META_MENU_OP_STICK | META_MENU_OP_UNSTICK | META_MENU_OP_WORKSPACES;
|
||||
|
||||
if ((window->type == META_WINDOW_DESKTOP) ||
|
||||
(window->type == META_WINDOW_DOCK) ||
|
||||
(window->type == META_WINDOW_SPLASHSCREEN ||
|
||||
META_WINDOW_MAXIMIZED (window)))
|
||||
insensitive |= META_MENU_OP_ABOVE | META_MENU_OP_UNABOVE;
|
||||
|
||||
/* If all operations are disabled, just quit without showing the menu.
|
||||
* This is the case, for example, with META_WINDOW_DESKTOP windows.
|
||||
*/
|
||||
if ((ops & ~insensitive) == 0)
|
||||
return;
|
||||
|
||||
menu =
|
||||
meta_ui_window_menu_new (window->screen->ui,
|
||||
window->xwindow,
|
||||
ops,
|
||||
insensitive,
|
||||
meta_window_get_net_wm_desktop (window),
|
||||
meta_screen_get_n_workspaces (window->screen),
|
||||
menu_callback,
|
||||
NULL);
|
||||
|
||||
window->display->window_menu = menu;
|
||||
window->display->window_with_menu = window;
|
||||
|
||||
meta_verbose ("Popping up window menu for %s\n", window->desc);
|
||||
|
||||
meta_ui_window_menu_popup (menu, root_x, root_y, button, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
@ -11245,13 +10970,7 @@ meta_window_get_frame_type (MetaWindow *window)
|
||||
cairo_region_t *
|
||||
meta_window_get_frame_bounds (MetaWindow *window)
|
||||
{
|
||||
if (!window->frame_bounds)
|
||||
{
|
||||
if (window->frame)
|
||||
window->frame_bounds = meta_frame_get_frame_bounds (window->frame);
|
||||
}
|
||||
|
||||
return window->frame_bounds;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
143
src/gtk-decorator/gtk-decorator.c
Normal file
143
src/gtk-decorator/gtk-decorator.c
Normal file
@ -0,0 +1,143 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Written by:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
|
||||
typedef struct {
|
||||
Display *xdisplay;
|
||||
} Decorator;
|
||||
|
||||
typedef struct {
|
||||
Decorator decorator;
|
||||
Window child_window;
|
||||
|
||||
GtkWidget *window;
|
||||
GtkWidget *socket;
|
||||
} WindowFrame;
|
||||
|
||||
static void
|
||||
socket_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation,
|
||||
gpointer user_data)
|
||||
{
|
||||
WindowFrame *frame = user_data;
|
||||
|
||||
XMoveResizeWindow (GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget)),
|
||||
frame->child_window,
|
||||
allocation->x, allocation->y,
|
||||
allocation->width, allocation->height);
|
||||
}
|
||||
|
||||
static WindowFrame *
|
||||
frame_window (Decorator *decorator,
|
||||
Window child_window)
|
||||
{
|
||||
WindowFrame *frame;
|
||||
XWindowAttributes attrs;
|
||||
GtkWidget *window, *socket;
|
||||
|
||||
XGetWindowAttributes (decorator->xdisplay, child_window, &attrs);
|
||||
|
||||
frame = g_slice_new0 (WindowFrame);
|
||||
frame->child_window = child_window;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
frame->window = window;
|
||||
gtk_window_move (GTK_WINDOW (window), attrs.x, attrs.y);
|
||||
|
||||
socket = gtk_frame_new (NULL);
|
||||
frame->socket = socket;
|
||||
gtk_widget_set_size_request (socket, attrs.width, attrs.height);
|
||||
g_signal_connect (socket, "size-allocate",
|
||||
G_CALLBACK (socket_size_allocate), frame);
|
||||
gtk_container_add (GTK_CONTAINER (window), socket);
|
||||
|
||||
gtk_widget_show (socket);
|
||||
gtk_widget_show (window);
|
||||
|
||||
XReparentWindow (decorator->xdisplay,
|
||||
child_window,
|
||||
GDK_WINDOW_XID (gtk_widget_get_window (window)),
|
||||
/* these will be positioned correctly at the
|
||||
* next size-allocate pass... */
|
||||
0, 0);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
static Window
|
||||
find_test_window (Display *dpy)
|
||||
{
|
||||
Window root, parent;
|
||||
Window *children;
|
||||
Window ret = None;
|
||||
unsigned int i, n_children;
|
||||
|
||||
XQueryTree (dpy, DefaultRootWindow (dpy),
|
||||
&root, &parent,
|
||||
&children, &n_children);
|
||||
|
||||
for (i = 0; i < n_children; i++)
|
||||
{
|
||||
Window child = children[i];
|
||||
char *name;
|
||||
|
||||
XFetchName (dpy, child, &name);
|
||||
if (g_strcmp0 (name, "this is a test window") == 0)
|
||||
ret = child;
|
||||
|
||||
g_free (name);
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
decorator_init (Decorator *decorator)
|
||||
{
|
||||
decorator->xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
Decorator decorator;
|
||||
Window window;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
decorator_init (&decorator);
|
||||
|
||||
window = find_test_window (decorator.xdisplay);
|
||||
frame_window (&decorator, window);
|
||||
|
||||
gtk_main ();
|
||||
return 0;
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Mutter gradient rendering */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in
|
||||
* WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef META_GRADIENT_H
|
||||
#define META_GRADIENT_H
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
/**
|
||||
* MetaGradientType:
|
||||
* @META_GRADIENT_VERTICAL: Vertical gradient
|
||||
* @META_GRADIENT_HORIZONTAL: Horizontal gradient
|
||||
* @META_GRADIENT_DIAGONAL: Diagonal gradient
|
||||
* @META_GRADIENT_LAST: Marks the end of the #MetaGradientType enumeration
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
META_GRADIENT_VERTICAL,
|
||||
META_GRADIENT_HORIZONTAL,
|
||||
META_GRADIENT_DIAGONAL,
|
||||
META_GRADIENT_LAST
|
||||
} MetaGradientType;
|
||||
|
||||
GdkPixbuf* meta_gradient_create_simple (int width,
|
||||
int height,
|
||||
const GdkRGBA *from,
|
||||
const GdkRGBA *to,
|
||||
MetaGradientType style);
|
||||
GdkPixbuf* meta_gradient_create_multi (int width,
|
||||
int height,
|
||||
const GdkRGBA *colors,
|
||||
int n_colors,
|
||||
MetaGradientType style);
|
||||
GdkPixbuf* meta_gradient_create_interwoven (int width,
|
||||
int height,
|
||||
const GdkRGBA colors1[2],
|
||||
int thickness1,
|
||||
const GdkRGBA colors2[2],
|
||||
int thickness2);
|
||||
|
||||
|
||||
/* Generate an alpha gradient and multiply it with the existing alpha
|
||||
* channel of the given pixbuf
|
||||
*/
|
||||
void meta_gradient_add_alpha (GdkPixbuf *pixbuf,
|
||||
const guchar *alphas,
|
||||
int n_alphas,
|
||||
MetaGradientType type);
|
||||
|
||||
|
||||
#endif
|
@ -24,7 +24,6 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include <meta/gradient.h>
|
||||
#include <meta/screen.h>
|
||||
|
||||
#include <gsettings-desktop-schemas/gdesktop-enums.h>
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <cogl/cogl.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include <meta/gradient.h>
|
||||
#include <meta/screen.h>
|
||||
|
||||
#include <gsettings-desktop-schemas/gdesktop-enums.h>
|
||||
|
@ -43,7 +43,6 @@
|
||||
* @META_PREF_AUTO_RAISE: auto-raise
|
||||
* @META_PREF_AUTO_RAISE_DELAY: auto-raise delay
|
||||
* @META_PREF_FOCUS_CHANGE_ON_POINTER_REST: focus change on pointer rest
|
||||
* @META_PREF_THEME: theme
|
||||
* @META_PREF_TITLEBAR_FONT: title-bar font
|
||||
* @META_PREF_NUM_WORKSPACES: number of workspaces
|
||||
* @META_PREF_DYNAMIC_WORKSPACES: dynamic workspaces
|
||||
@ -80,7 +79,6 @@ typedef enum
|
||||
META_PREF_AUTO_RAISE,
|
||||
META_PREF_AUTO_RAISE_DELAY,
|
||||
META_PREF_FOCUS_CHANGE_ON_POINTER_REST,
|
||||
META_PREF_THEME,
|
||||
META_PREF_TITLEBAR_FONT,
|
||||
META_PREF_NUM_WORKSPACES,
|
||||
META_PREF_DYNAMIC_WORKSPACES,
|
||||
@ -125,7 +123,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);
|
||||
|
@ -111,7 +111,6 @@ gint meta_unsigned_long_equal (gconstpointer v1,
|
||||
gconstpointer v2);
|
||||
guint meta_unsigned_long_hash (gconstpointer v);
|
||||
|
||||
const char* meta_frame_type_to_string (MetaFrameType type);
|
||||
const char* meta_gravity_to_string (int gravity);
|
||||
|
||||
char* meta_external_binding_name_for_action (guint keybinding_action);
|
||||
|
2412
src/ui/frames.c
2412
src/ui/frames.c
File diff suppressed because it is too large
Load Diff
160
src/ui/frames.h
160
src/ui/frames.h
@ -1,160 +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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_FRAMES_H
|
||||
#define META_FRAMES_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <meta/common.h>
|
||||
#include "theme-private.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_SHADE,
|
||||
META_FRAME_CONTROL_UNSHADE,
|
||||
META_FRAME_CONTROL_ABOVE,
|
||||
META_FRAME_CONTROL_UNABOVE,
|
||||
META_FRAME_CONTROL_STICK,
|
||||
META_FRAME_CONTROL_UNSTICK,
|
||||
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;
|
||||
|
||||
typedef struct _MetaUIFrame MetaUIFrame;
|
||||
|
||||
struct _MetaUIFrame
|
||||
{
|
||||
Window xwindow;
|
||||
GdkWindow *window;
|
||||
GtkStyleContext *style;
|
||||
MetaFrameStyle *cache_style;
|
||||
PangoLayout *layout;
|
||||
int text_height;
|
||||
char *title; /* NULL once we have a layout */
|
||||
guint shape_applied : 1;
|
||||
|
||||
/* FIXME get rid of this, it can just be in the MetaFrames struct */
|
||||
MetaFrameControl prelit_control;
|
||||
};
|
||||
|
||||
struct _MetaFrames
|
||||
{
|
||||
GtkWindow parent_instance;
|
||||
|
||||
GHashTable *text_heights;
|
||||
|
||||
GHashTable *frames;
|
||||
MetaUIFrame *last_motion_frame;
|
||||
|
||||
GtkStyleContext *normal_style;
|
||||
GHashTable *style_variants;
|
||||
};
|
||||
|
||||
struct _MetaFramesClass
|
||||
{
|
||||
GtkWindowClass parent_class;
|
||||
|
||||
};
|
||||
|
||||
GType meta_frames_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaFrames *meta_frames_new (int screen_number);
|
||||
|
||||
void meta_frames_manage_window (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
GdkWindow *window);
|
||||
void meta_frames_unmanage_window (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
void meta_frames_set_title (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
const char *title);
|
||||
|
||||
void meta_frames_update_frame_style (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
|
||||
void meta_frames_repaint_frame (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
|
||||
void meta_frames_get_borders (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
MetaFrameBorders *borders);
|
||||
|
||||
void meta_frames_reset_bg (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
void meta_frames_unflicker_bg (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
int target_width,
|
||||
int target_height);
|
||||
|
||||
cairo_region_t *meta_frames_get_frame_bounds (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
int window_width,
|
||||
int window_height);
|
||||
|
||||
void meta_frames_get_mask (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
guint width,
|
||||
guint height,
|
||||
cairo_t *cr);
|
||||
|
||||
void meta_frames_move_resize_frame (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void meta_frames_queue_draw (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
|
||||
void meta_frames_notify_menu_hide (MetaFrames *frames);
|
||||
|
||||
Window meta_frames_get_moving_frame (MetaFrames *frames);
|
||||
|
||||
#endif
|
@ -1,873 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in
|
||||
* WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima
|
||||
* Copyright (C) 2005 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/**
|
||||
* SECTION:gradient
|
||||
* @title: Gradients
|
||||
* @short_description: Metacity gradient rendering
|
||||
*/
|
||||
|
||||
#include <meta/gradient.h>
|
||||
#include <meta/util.h>
|
||||
#include <string.h>
|
||||
|
||||
/* This is all Alfredo's and Dan's usual very nice WindowMaker code,
|
||||
* slightly GTK-ized
|
||||
*/
|
||||
static GdkPixbuf* meta_gradient_create_horizontal (int width,
|
||||
int height,
|
||||
const GdkRGBA *from,
|
||||
const GdkRGBA *to);
|
||||
static GdkPixbuf* meta_gradient_create_vertical (int width,
|
||||
int height,
|
||||
const GdkRGBA *from,
|
||||
const GdkRGBA *to);
|
||||
static GdkPixbuf* meta_gradient_create_diagonal (int width,
|
||||
int height,
|
||||
const GdkRGBA *from,
|
||||
const GdkRGBA *to);
|
||||
static GdkPixbuf* meta_gradient_create_multi_horizontal (int width,
|
||||
int height,
|
||||
const GdkRGBA *colors,
|
||||
int count);
|
||||
static GdkPixbuf* meta_gradient_create_multi_vertical (int width,
|
||||
int height,
|
||||
const GdkRGBA *colors,
|
||||
int count);
|
||||
static GdkPixbuf* meta_gradient_create_multi_diagonal (int width,
|
||||
int height,
|
||||
const GdkRGBA *colors,
|
||||
int count);
|
||||
|
||||
|
||||
/* Used as the destroy notification function for gdk_pixbuf_new() */
|
||||
static void
|
||||
free_buffer (guchar *pixels, gpointer data)
|
||||
{
|
||||
g_free (pixels);
|
||||
}
|
||||
|
||||
static GdkPixbuf*
|
||||
blank_pixbuf (int width, int height, gboolean no_padding)
|
||||
{
|
||||
guchar *buf;
|
||||
int rowstride;
|
||||
|
||||
g_return_val_if_fail (width > 0, NULL);
|
||||
g_return_val_if_fail (height > 0, NULL);
|
||||
|
||||
if (no_padding)
|
||||
rowstride = width * 3;
|
||||
else
|
||||
/* Always align rows to 32-bit boundaries */
|
||||
rowstride = 4 * ((3 * width + 3) / 4);
|
||||
|
||||
buf = g_try_malloc (height * rowstride);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
return gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB,
|
||||
FALSE, 8,
|
||||
width, height, rowstride,
|
||||
free_buffer, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_gradient_create_simple:
|
||||
* @width: Width in pixels
|
||||
* @height: Height in pixels
|
||||
* @from: Starting color
|
||||
* @to: Ending color
|
||||
* @style: Gradient style
|
||||
*
|
||||
* Returns: (transfer full): A new linear gradient
|
||||
*/
|
||||
GdkPixbuf*
|
||||
meta_gradient_create_simple (int width,
|
||||
int height,
|
||||
const GdkRGBA *from,
|
||||
const GdkRGBA *to,
|
||||
MetaGradientType style)
|
||||
{
|
||||
switch (style)
|
||||
{
|
||||
case META_GRADIENT_HORIZONTAL:
|
||||
return meta_gradient_create_horizontal (width, height,
|
||||
from, to);
|
||||
case META_GRADIENT_VERTICAL:
|
||||
return meta_gradient_create_vertical (width, height,
|
||||
from, to);
|
||||
|
||||
case META_GRADIENT_DIAGONAL:
|
||||
return meta_gradient_create_diagonal (width, height,
|
||||
from, to);
|
||||
case META_GRADIENT_LAST:
|
||||
break;
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_gradient_create_multi:
|
||||
* @width: Width in pixels
|
||||
* @height: Height in pixels
|
||||
* @colors: (array length=n_colors): Array of colors
|
||||
* @n_colors: Number of colors
|
||||
* @style: Gradient style
|
||||
*
|
||||
* Returns: (transfer full): A new multi-step linear gradient
|
||||
*/
|
||||
GdkPixbuf*
|
||||
meta_gradient_create_multi (int width,
|
||||
int height,
|
||||
const GdkRGBA *colors,
|
||||
int n_colors,
|
||||
MetaGradientType style)
|
||||
{
|
||||
|
||||
if (n_colors > 2)
|
||||
{
|
||||
switch (style)
|
||||
{
|
||||
case META_GRADIENT_HORIZONTAL:
|
||||
return meta_gradient_create_multi_horizontal (width, height, colors, n_colors);
|
||||
case META_GRADIENT_VERTICAL:
|
||||
return meta_gradient_create_multi_vertical (width, height, colors, n_colors);
|
||||
case META_GRADIENT_DIAGONAL:
|
||||
return meta_gradient_create_multi_diagonal (width, height, colors, n_colors);
|
||||
case META_GRADIENT_LAST:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (n_colors > 1)
|
||||
{
|
||||
return meta_gradient_create_simple (width, height, &colors[0], &colors[1],
|
||||
style);
|
||||
}
|
||||
else if (n_colors > 0)
|
||||
{
|
||||
return meta_gradient_create_simple (width, height, &colors[0], &colors[0],
|
||||
style);
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_gradient_create_interwoven: (skip)
|
||||
* @width: Width in pixels
|
||||
* @height: Height in pixels
|
||||
* @colors1: Array of colors
|
||||
* @thickness1: Thickness
|
||||
* @colors2: Array of colors
|
||||
* @thickness2: Thickness
|
||||
*
|
||||
* Interwoven essentially means we have two vertical gradients,
|
||||
* cut into horizontal strips of the given thickness, and then the strips
|
||||
* are alternated. I'm not sure what it's good for, just copied since
|
||||
* WindowMaker had it.
|
||||
*/
|
||||
GdkPixbuf*
|
||||
meta_gradient_create_interwoven (int width,
|
||||
int height,
|
||||
const GdkRGBA colors1[2],
|
||||
int thickness1,
|
||||
const GdkRGBA colors2[2],
|
||||
int thickness2)
|
||||
{
|
||||
|
||||
int i, j, k, l, ll;
|
||||
long r1, g1, b1, dr1, dg1, db1;
|
||||
long r2, g2, b2, dr2, dg2, db2;
|
||||
GdkPixbuf *pixbuf;
|
||||
unsigned char *ptr;
|
||||
unsigned char *pixels;
|
||||
int rowstride;
|
||||
|
||||
pixbuf = blank_pixbuf (width, height, FALSE);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
|
||||
r1 = (long)(colors1[0].red*0xffffff);
|
||||
g1 = (long)(colors1[0].green*0xffffff);
|
||||
b1 = (long)(colors1[0].blue*0xffffff);
|
||||
|
||||
r2 = (long)(colors2[0].red*0xffffff);
|
||||
g2 = (long)(colors2[0].green*0xffffff);
|
||||
b2 = (long)(colors2[0].blue*0xffffff);
|
||||
|
||||
dr1 = ((colors1[1].red-colors1[0].red)*0xffffff)/(int)height;
|
||||
dg1 = ((colors1[1].green-colors1[0].green)*0xffffff)/(int)height;
|
||||
db1 = ((colors1[1].blue-colors1[0].blue)*0xffffff)/(int)height;
|
||||
|
||||
dr2 = ((colors2[1].red-colors2[0].red)*0xffffff)/(int)height;
|
||||
dg2 = ((colors2[1].green-colors2[0].green)*0xffffff)/(int)height;
|
||||
db2 = ((colors2[1].blue-colors2[0].blue)*0xffffff)/(int)height;
|
||||
|
||||
for (i=0,k=0,l=0,ll=thickness1; i<height; i++)
|
||||
{
|
||||
ptr = pixels + i * rowstride;
|
||||
|
||||
if (k == 0)
|
||||
{
|
||||
ptr[0] = (unsigned char) (r1>>16);
|
||||
ptr[1] = (unsigned char) (g1>>16);
|
||||
ptr[2] = (unsigned char) (b1>>16);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr[0] = (unsigned char) (r2>>16);
|
||||
ptr[1] = (unsigned char) (g2>>16);
|
||||
ptr[2] = (unsigned char) (b2>>16);
|
||||
}
|
||||
|
||||
for (j=1; j <= width/2; j *= 2)
|
||||
memcpy (&(ptr[j*3]), ptr, j*3);
|
||||
memcpy (&(ptr[j*3]), ptr, (width - j)*3);
|
||||
|
||||
if (++l == ll)
|
||||
{
|
||||
if (k == 0)
|
||||
{
|
||||
k = 1;
|
||||
ll = thickness2;
|
||||
}
|
||||
else
|
||||
{
|
||||
k = 0;
|
||||
ll = thickness1;
|
||||
}
|
||||
l = 0;
|
||||
}
|
||||
r1+=dr1;
|
||||
g1+=dg1;
|
||||
b1+=db1;
|
||||
|
||||
r2+=dr2;
|
||||
g2+=dg2;
|
||||
b2+=db2;
|
||||
}
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* meta_gradient_create_horizontal--
|
||||
* Renders a horizontal linear gradient of the specified size in the
|
||||
* GdkPixbuf format with a border of the specified type.
|
||||
*
|
||||
* Returns:
|
||||
* A 24bit GdkPixbuf with the gradient (no alpha channel).
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
static GdkPixbuf*
|
||||
meta_gradient_create_horizontal (int width, int height,
|
||||
const GdkRGBA *from,
|
||||
const GdkRGBA *to)
|
||||
{
|
||||
int i;
|
||||
long r, g, b, dr, dg, db;
|
||||
GdkPixbuf *pixbuf;
|
||||
unsigned char *ptr;
|
||||
unsigned char *pixels;
|
||||
int r0, g0, b0;
|
||||
int rf, gf, bf;
|
||||
int rowstride;
|
||||
|
||||
pixbuf = blank_pixbuf (width, height, FALSE);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
ptr = pixels;
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
|
||||
r0 = (guchar) (from->red * 0xff);
|
||||
g0 = (guchar) (from->green * 0xff);
|
||||
b0 = (guchar) (from->blue * 0xff);
|
||||
rf = (guchar) (to->red * 0xff);
|
||||
gf = (guchar) (to->green * 0xff);
|
||||
bf = (guchar) (to->blue * 0xff);
|
||||
|
||||
r = r0 << 16;
|
||||
g = g0 << 16;
|
||||
b = b0 << 16;
|
||||
|
||||
dr = ((rf-r0)<<16)/(int)width;
|
||||
dg = ((gf-g0)<<16)/(int)width;
|
||||
db = ((bf-b0)<<16)/(int)width;
|
||||
/* render the first line */
|
||||
for (i=0; i<width; i++)
|
||||
{
|
||||
*(ptr++) = (unsigned char)(r>>16);
|
||||
*(ptr++) = (unsigned char)(g>>16);
|
||||
*(ptr++) = (unsigned char)(b>>16);
|
||||
r += dr;
|
||||
g += dg;
|
||||
b += db;
|
||||
}
|
||||
|
||||
/* copy the first line to the other lines */
|
||||
for (i=1; i<height; i++)
|
||||
{
|
||||
memcpy (&(pixels[i*rowstride]), pixels, rowstride);
|
||||
}
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* meta_gradient_create_vertical--
|
||||
* Renders a vertical linear gradient of the specified size in the
|
||||
* GdkPixbuf format with a border of the specified type.
|
||||
*
|
||||
* Returns:
|
||||
* A 24bit GdkPixbuf with the gradient (no alpha channel).
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
static GdkPixbuf*
|
||||
meta_gradient_create_vertical (int width, int height,
|
||||
const GdkRGBA *from,
|
||||
const GdkRGBA *to)
|
||||
{
|
||||
int i, j;
|
||||
long r, g, b, dr, dg, db;
|
||||
GdkPixbuf *pixbuf;
|
||||
unsigned char *ptr;
|
||||
int r0, g0, b0;
|
||||
int rf, gf, bf;
|
||||
int rowstride;
|
||||
unsigned char *pixels;
|
||||
|
||||
pixbuf = blank_pixbuf (width, height, FALSE);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
|
||||
r0 = (guchar) (from->red * 0xff);
|
||||
g0 = (guchar) (from->green * 0xff);
|
||||
b0 = (guchar) (from->blue * 0xff);
|
||||
rf = (guchar) (to->red * 0xff);
|
||||
gf = (guchar) (to->green * 0xff);
|
||||
bf = (guchar) (to->blue * 0xff);
|
||||
|
||||
r = r0<<16;
|
||||
g = g0<<16;
|
||||
b = b0<<16;
|
||||
|
||||
dr = ((rf-r0)<<16)/(int)height;
|
||||
dg = ((gf-g0)<<16)/(int)height;
|
||||
db = ((bf-b0)<<16)/(int)height;
|
||||
|
||||
for (i=0; i<height; i++)
|
||||
{
|
||||
ptr = pixels + i * rowstride;
|
||||
|
||||
ptr[0] = (unsigned char)(r>>16);
|
||||
ptr[1] = (unsigned char)(g>>16);
|
||||
ptr[2] = (unsigned char)(b>>16);
|
||||
|
||||
for (j=1; j <= width/2; j *= 2)
|
||||
memcpy (&(ptr[j*3]), ptr, j*3);
|
||||
memcpy (&(ptr[j*3]), ptr, (width - j)*3);
|
||||
|
||||
r+=dr;
|
||||
g+=dg;
|
||||
b+=db;
|
||||
}
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* meta_gradient_create_diagonal--
|
||||
* Renders a diagonal linear gradient of the specified size in the
|
||||
* GdkPixbuf format with a border of the specified type.
|
||||
*
|
||||
* Returns:
|
||||
* A 24bit GdkPixbuf with the gradient (no alpha channel).
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
static GdkPixbuf*
|
||||
meta_gradient_create_diagonal (int width, int height,
|
||||
const GdkRGBA *from,
|
||||
const GdkRGBA *to)
|
||||
{
|
||||
GdkPixbuf *pixbuf, *tmp;
|
||||
int j;
|
||||
float a, offset;
|
||||
unsigned char *ptr;
|
||||
unsigned char *pixels;
|
||||
int rowstride;
|
||||
|
||||
if (width == 1)
|
||||
return meta_gradient_create_vertical (width, height, from, to);
|
||||
else if (height == 1)
|
||||
return meta_gradient_create_horizontal (width, height, from, to);
|
||||
|
||||
pixbuf = blank_pixbuf (width, height, FALSE);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
|
||||
tmp = meta_gradient_create_horizontal (2*width-1, 1, from, to);
|
||||
if (!tmp)
|
||||
{
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = gdk_pixbuf_get_pixels (tmp);
|
||||
|
||||
a = ((float)(width - 1))/((float)(height - 1));
|
||||
width = width * 3;
|
||||
|
||||
/* copy the first line to the other lines with corresponding offset */
|
||||
for (j=0, offset=0.0; j<rowstride*height; j += rowstride)
|
||||
{
|
||||
memcpy (&(pixels[j]), &ptr[3*(int)offset], width);
|
||||
offset += a;
|
||||
}
|
||||
|
||||
g_object_unref (G_OBJECT (tmp));
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
|
||||
static GdkPixbuf*
|
||||
meta_gradient_create_multi_horizontal (int width, int height,
|
||||
const GdkRGBA *colors,
|
||||
int count)
|
||||
{
|
||||
int i, j, k;
|
||||
long r, g, b, dr, dg, db;
|
||||
GdkPixbuf *pixbuf;
|
||||
unsigned char *ptr;
|
||||
unsigned char *pixels;
|
||||
int width2;
|
||||
int rowstride;
|
||||
|
||||
g_return_val_if_fail (count > 2, NULL);
|
||||
|
||||
pixbuf = blank_pixbuf (width, height, FALSE);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
ptr = pixels;
|
||||
|
||||
if (count > width)
|
||||
count = width;
|
||||
|
||||
if (count > 1)
|
||||
width2 = width/(count-1);
|
||||
else
|
||||
width2 = width;
|
||||
|
||||
k = 0;
|
||||
|
||||
r = (long)(colors[0].red * 0xffffff);
|
||||
g = (long)(colors[0].green * 0xffffff);
|
||||
b = (long)(colors[0].blue * 0xffffff);
|
||||
|
||||
/* render the first line */
|
||||
for (i=1; i<count; i++)
|
||||
{
|
||||
dr = (int)((colors[i].red - colors[i-1].red) *0xffffff)/(int)width2;
|
||||
dg = (int)((colors[i].green - colors[i-1].green)*0xffffff)/(int)width2;
|
||||
db = (int)((colors[i].blue - colors[i-1].blue) *0xffffff)/(int)width2;
|
||||
for (j=0; j<width2; j++)
|
||||
{
|
||||
*ptr++ = (unsigned char)(r>>16);
|
||||
*ptr++ = (unsigned char)(g>>16);
|
||||
*ptr++ = (unsigned char)(b>>16);
|
||||
r += dr;
|
||||
g += dg;
|
||||
b += db;
|
||||
k++;
|
||||
}
|
||||
r = (long)(colors[i].red * 0xffffff);
|
||||
g = (long)(colors[i].green * 0xffffff);
|
||||
b = (long)(colors[i].blue * 0xffffff);
|
||||
}
|
||||
for (j=k; j<width; j++)
|
||||
{
|
||||
*ptr++ = (unsigned char)(r>>16);
|
||||
*ptr++ = (unsigned char)(g>>16);
|
||||
*ptr++ = (unsigned char)(b>>16);
|
||||
}
|
||||
|
||||
/* copy the first line to the other lines */
|
||||
for (i=1; i<height; i++)
|
||||
{
|
||||
memcpy (&(pixels[i*rowstride]), pixels, rowstride);
|
||||
}
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
static GdkPixbuf*
|
||||
meta_gradient_create_multi_vertical (int width, int height,
|
||||
const GdkRGBA *colors,
|
||||
int count)
|
||||
{
|
||||
int i, j, k;
|
||||
long r, g, b, dr, dg, db;
|
||||
GdkPixbuf *pixbuf;
|
||||
unsigned char *ptr, *tmp, *pixels;
|
||||
int height2;
|
||||
int x;
|
||||
int rowstride;
|
||||
|
||||
g_return_val_if_fail (count > 2, NULL);
|
||||
|
||||
pixbuf = blank_pixbuf (width, height, FALSE);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
ptr = pixels;
|
||||
|
||||
if (count > height)
|
||||
count = height;
|
||||
|
||||
if (count > 1)
|
||||
height2 = height/(count-1);
|
||||
else
|
||||
height2 = height;
|
||||
|
||||
k = 0;
|
||||
|
||||
r = (long)(colors[0].red * 0xffffff);
|
||||
g = (long)(colors[0].green * 0xffffff);
|
||||
b = (long)(colors[0].blue * 0xffffff);
|
||||
|
||||
for (i=1; i<count; i++)
|
||||
{
|
||||
dr = (int)((colors[i].red - colors[i-1].red) *0xffffff)/(int)height2;
|
||||
dg = (int)((colors[i].green - colors[i-1].green)*0xffffff)/(int)height2;
|
||||
db = (int)((colors[i].blue - colors[i-1].blue) *0xffffff)/(int)height2;
|
||||
|
||||
for (j=0; j<height2; j++)
|
||||
{
|
||||
ptr[0] = (unsigned char)(r>>16);
|
||||
ptr[1] = (unsigned char)(g>>16);
|
||||
ptr[2] = (unsigned char)(b>>16);
|
||||
|
||||
for (x=1; x <= width/2; x *= 2)
|
||||
memcpy (&(ptr[x*3]), ptr, x*3);
|
||||
memcpy (&(ptr[x*3]), ptr, (width - x)*3);
|
||||
|
||||
ptr += rowstride;
|
||||
|
||||
r += dr;
|
||||
g += dg;
|
||||
b += db;
|
||||
k++;
|
||||
}
|
||||
r = (long)(colors[i].red * 0xffffff);
|
||||
g = (long)(colors[i].green * 0xffffff);
|
||||
b = (long)(colors[i].blue * 0xffffff);
|
||||
}
|
||||
|
||||
if (k<height)
|
||||
{
|
||||
tmp = ptr;
|
||||
|
||||
ptr[0] = (unsigned char) (r>>16);
|
||||
ptr[1] = (unsigned char) (g>>16);
|
||||
ptr[2] = (unsigned char) (b>>16);
|
||||
|
||||
for (x=1; x <= width/2; x *= 2)
|
||||
memcpy (&(ptr[x*3]), ptr, x*3);
|
||||
memcpy (&(ptr[x*3]), ptr, (width - x)*3);
|
||||
|
||||
ptr += rowstride;
|
||||
|
||||
for (j=k+1; j<height; j++)
|
||||
{
|
||||
memcpy (ptr, tmp, rowstride);
|
||||
ptr += rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
|
||||
static GdkPixbuf*
|
||||
meta_gradient_create_multi_diagonal (int width, int height,
|
||||
const GdkRGBA *colors,
|
||||
int count)
|
||||
{
|
||||
GdkPixbuf *pixbuf, *tmp;
|
||||
float a, offset;
|
||||
int j;
|
||||
unsigned char *ptr;
|
||||
unsigned char *pixels;
|
||||
int rowstride;
|
||||
|
||||
g_return_val_if_fail (count > 2, NULL);
|
||||
|
||||
if (width == 1)
|
||||
return meta_gradient_create_multi_vertical (width, height, colors, count);
|
||||
else if (height == 1)
|
||||
return meta_gradient_create_multi_horizontal (width, height, colors, count);
|
||||
|
||||
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
|
||||
width, height);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
|
||||
if (count > width)
|
||||
count = width;
|
||||
if (count > height)
|
||||
count = height;
|
||||
|
||||
if (count > 2)
|
||||
tmp = meta_gradient_create_multi_horizontal (2*width-1, 1, colors, count);
|
||||
else
|
||||
/* wrlib multiplies these colors by 256 before passing them in, but
|
||||
* I think it's a bug in wrlib, so changed here. I could be wrong
|
||||
* though, if we notice two-color multi diagonals not working.
|
||||
*/
|
||||
tmp = meta_gradient_create_horizontal (2*width-1, 1,
|
||||
&colors[0], &colors[1]);
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
return NULL;
|
||||
}
|
||||
ptr = gdk_pixbuf_get_pixels (tmp);
|
||||
|
||||
a = ((float)(width - 1))/((float)(height - 1));
|
||||
width = width * 3;
|
||||
|
||||
/* copy the first line to the other lines with corresponding offset */
|
||||
for (j=0, offset=0; j<rowstride*height; j += rowstride)
|
||||
{
|
||||
memcpy (&(pixels[j]), &ptr[3*(int)offset], width);
|
||||
offset += a;
|
||||
}
|
||||
|
||||
g_object_unref (G_OBJECT (tmp));
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
simple_multiply_alpha (GdkPixbuf *pixbuf,
|
||||
guchar alpha)
|
||||
{
|
||||
guchar *pixels;
|
||||
int rowstride;
|
||||
int height;
|
||||
int row;
|
||||
|
||||
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
|
||||
|
||||
if (alpha == 255)
|
||||
return;
|
||||
|
||||
g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
|
||||
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
height = gdk_pixbuf_get_height (pixbuf);
|
||||
|
||||
row = 0;
|
||||
while (row < height)
|
||||
{
|
||||
guchar *p;
|
||||
guchar *end;
|
||||
|
||||
p = pixels + row * rowstride;
|
||||
end = p + rowstride;
|
||||
|
||||
while (p != end)
|
||||
{
|
||||
p += 3; /* skip RGB */
|
||||
|
||||
/* multiply the two alpha channels. not sure this is right.
|
||||
* but some end cases are that if the pixbuf contains 255,
|
||||
* then it should be modified to contain "alpha"; if the
|
||||
* pixbuf contains 0, it should remain 0.
|
||||
*/
|
||||
/* ((*p / 255.0) * (alpha / 255.0)) * 255; */
|
||||
*p = (guchar) (((int) *p * (int) alpha) / (int) 255);
|
||||
|
||||
++p; /* skip A */
|
||||
}
|
||||
|
||||
++row;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_gradient_add_alpha_horizontal (GdkPixbuf *pixbuf,
|
||||
const unsigned char *alphas,
|
||||
int n_alphas)
|
||||
{
|
||||
int i, j;
|
||||
long a, da;
|
||||
unsigned char *p;
|
||||
unsigned char *pixels;
|
||||
int width2;
|
||||
int rowstride;
|
||||
int width, height;
|
||||
unsigned char *gradient;
|
||||
unsigned char *gradient_p;
|
||||
unsigned char *gradient_end;
|
||||
|
||||
g_return_if_fail (n_alphas > 0);
|
||||
|
||||
if (n_alphas == 1)
|
||||
{
|
||||
/* Optimize this */
|
||||
simple_multiply_alpha (pixbuf, alphas[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
width = gdk_pixbuf_get_width (pixbuf);
|
||||
height = gdk_pixbuf_get_height (pixbuf);
|
||||
|
||||
gradient = g_new (unsigned char, width);
|
||||
gradient_end = gradient + width;
|
||||
|
||||
if (n_alphas > width)
|
||||
n_alphas = width;
|
||||
|
||||
if (n_alphas > 1)
|
||||
width2 = width / (n_alphas - 1);
|
||||
else
|
||||
width2 = width;
|
||||
|
||||
a = alphas[0] << 8;
|
||||
gradient_p = gradient;
|
||||
|
||||
/* render the gradient into an array */
|
||||
for (i = 1; i < n_alphas; i++)
|
||||
{
|
||||
da = (((int)(alphas[i] - (int) alphas[i-1])) << 8) / (int) width2;
|
||||
|
||||
for (j = 0; j < width2; j++)
|
||||
{
|
||||
*gradient_p++ = (a >> 8);
|
||||
|
||||
a += da;
|
||||
}
|
||||
|
||||
a = alphas[i] << 8;
|
||||
}
|
||||
|
||||
/* get leftover pixels */
|
||||
while (gradient_p != gradient_end)
|
||||
{
|
||||
*gradient_p++ = a >> 8;
|
||||
}
|
||||
|
||||
/* Now for each line of the pixbuf, fill in with the gradient */
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
|
||||
p = pixels;
|
||||
i = 0;
|
||||
while (i < height)
|
||||
{
|
||||
unsigned char *row_end = p + rowstride;
|
||||
gradient_p = gradient;
|
||||
|
||||
p += 3;
|
||||
while (gradient_p != gradient_end)
|
||||
{
|
||||
/* multiply the two alpha channels. not sure this is right.
|
||||
* but some end cases are that if the pixbuf contains 255,
|
||||
* then it should be modified to contain "alpha"; if the
|
||||
* pixbuf contains 0, it should remain 0.
|
||||
*/
|
||||
/* ((*p / 255.0) * (alpha / 255.0)) * 255; */
|
||||
*p = (guchar) (((int) *p * (int) *gradient_p) / (int) 255);
|
||||
|
||||
p += 4;
|
||||
++gradient_p;
|
||||
}
|
||||
|
||||
p = row_end;
|
||||
++i;
|
||||
}
|
||||
|
||||
g_free (gradient);
|
||||
}
|
||||
|
||||
void
|
||||
meta_gradient_add_alpha (GdkPixbuf *pixbuf,
|
||||
const guchar *alphas,
|
||||
int n_alphas,
|
||||
MetaGradientType type)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
|
||||
g_return_if_fail (gdk_pixbuf_get_has_alpha (pixbuf));
|
||||
g_return_if_fail (n_alphas > 0);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case META_GRADIENT_HORIZONTAL:
|
||||
meta_gradient_add_alpha_horizontal (pixbuf, alphas, n_alphas);
|
||||
break;
|
||||
|
||||
case META_GRADIENT_VERTICAL:
|
||||
g_printerr ("metacity: vertical alpha channel gradient not implemented yet\n");
|
||||
break;
|
||||
|
||||
case META_GRADIENT_DIAGONAL:
|
||||
g_printerr ("metacity: diagonal alpha channel gradient not implemented yet\n");
|
||||
break;
|
||||
|
||||
case META_GRADIENT_LAST:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
518
src/ui/menu.c
518
src/ui/menu.c
@ -1,518 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Mutter window menu */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2004 Rob Adams
|
||||
* Copyright (C) 2005 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "menu.h"
|
||||
#include <meta/main.h>
|
||||
#include "util-private.h"
|
||||
#include "core.h"
|
||||
#include "metaaccellabel.h"
|
||||
#include "ui.h"
|
||||
|
||||
typedef struct _MenuItem MenuItem;
|
||||
typedef struct _MenuData MenuData;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MENU_ITEM_SEPARATOR = 0,
|
||||
MENU_ITEM_NORMAL,
|
||||
MENU_ITEM_CHECKBOX,
|
||||
MENU_ITEM_RADIOBUTTON,
|
||||
MENU_ITEM_WORKSPACE_LIST,
|
||||
} MetaMenuItemType;
|
||||
|
||||
struct _MenuItem
|
||||
{
|
||||
MetaMenuOp op;
|
||||
MetaMenuItemType type;
|
||||
const gboolean checked;
|
||||
const char *label;
|
||||
};
|
||||
|
||||
|
||||
struct _MenuData
|
||||
{
|
||||
MetaWindowMenu *menu;
|
||||
MetaMenuOp op;
|
||||
};
|
||||
|
||||
static void activate_cb (GtkWidget *menuitem, gpointer data);
|
||||
|
||||
static MenuItem menuitems[] = {
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_MINIMIZE, MENU_ITEM_NORMAL, FALSE, N_("Mi_nimize") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_MAXIMIZE, MENU_ITEM_NORMAL, FALSE, N_("Ma_ximize") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_UNMAXIMIZE, MENU_ITEM_NORMAL, FALSE, N_("Unma_ximize") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_SHADE, MENU_ITEM_NORMAL, FALSE, N_("Roll _Up") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_UNSHADE, MENU_ITEM_NORMAL, FALSE, N_("_Unroll") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_MOVE, MENU_ITEM_NORMAL, FALSE, N_("_Move") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_RESIZE, MENU_ITEM_NORMAL, FALSE, N_("_Resize") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_RECOVER, MENU_ITEM_NORMAL, FALSE, N_("Move Titlebar On_screen") },
|
||||
{ META_MENU_OP_WORKSPACES, MENU_ITEM_SEPARATOR, FALSE, NULL }, /* separator */
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_ABOVE, MENU_ITEM_CHECKBOX, FALSE, N_("Always on _Top") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_UNABOVE, MENU_ITEM_CHECKBOX, TRUE, N_("Always on _Top") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_STICK, MENU_ITEM_RADIOBUTTON, FALSE, N_("_Always on Visible Workspace") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_UNSTICK, MENU_ITEM_RADIOBUTTON, FALSE, N_("_Only on This Workspace") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_MOVE_LEFT, MENU_ITEM_NORMAL, FALSE, N_("Move to Workspace _Left") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_MOVE_RIGHT, MENU_ITEM_NORMAL, FALSE, N_("Move to Workspace R_ight") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_MOVE_UP, MENU_ITEM_NORMAL, FALSE, N_("Move to Workspace _Up") },
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_MOVE_DOWN, MENU_ITEM_NORMAL, FALSE, N_("Move to Workspace _Down") },
|
||||
{ 0, MENU_ITEM_WORKSPACE_LIST, FALSE, NULL },
|
||||
{ 0, MENU_ITEM_SEPARATOR, FALSE, NULL }, /* separator */
|
||||
/* Translators: Translate this string the same way as you do in libwnck! */
|
||||
{ META_MENU_OP_DELETE, MENU_ITEM_NORMAL, FALSE, N_("_Close") }
|
||||
};
|
||||
|
||||
static void
|
||||
popup_position_func (GtkMenu *menu,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gboolean *push_in,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkRequisition req;
|
||||
GdkPoint *pos;
|
||||
|
||||
pos = user_data;
|
||||
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (menu), &req, NULL);
|
||||
|
||||
*x = pos->x;
|
||||
*y = pos->y;
|
||||
|
||||
if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
|
||||
*x = MAX (0, *x - req.width);
|
||||
|
||||
/* Ensure onscreen */
|
||||
*x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width));
|
||||
*y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
|
||||
}
|
||||
|
||||
static void
|
||||
menu_closed (GtkMenu *widget,
|
||||
gpointer data)
|
||||
{
|
||||
MetaWindowMenu *menu;
|
||||
|
||||
menu = data;
|
||||
|
||||
meta_frames_notify_menu_hide (menu->frames);
|
||||
(* menu->func) (menu,
|
||||
GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
|
||||
menu->client_xwindow,
|
||||
gtk_get_current_event_time (),
|
||||
0, 0,
|
||||
menu->data);
|
||||
|
||||
/* menu may now be freed */
|
||||
}
|
||||
|
||||
static void
|
||||
activate_cb (GtkWidget *menuitem, gpointer data)
|
||||
{
|
||||
MenuData *md;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (menuitem));
|
||||
|
||||
md = data;
|
||||
|
||||
meta_frames_notify_menu_hide (md->menu->frames);
|
||||
(* md->menu->func) (md->menu,
|
||||
GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
|
||||
md->menu->client_xwindow,
|
||||
gtk_get_current_event_time (),
|
||||
md->op,
|
||||
GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem),
|
||||
"workspace")),
|
||||
md->menu->data);
|
||||
|
||||
/* menu may now be freed */
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a Display and an index, get the workspace name and add any
|
||||
* accelerators. At the moment this means adding a _ if the name is of
|
||||
* the form "Workspace n" where n is less than 10, and escaping any
|
||||
* other '_'s so they do not create inadvertant accelerators.
|
||||
*
|
||||
* The calling code owns the string, and is reponsible to free the
|
||||
* memory after use.
|
||||
*
|
||||
* See also http://mail.gnome.org/archives/gnome-i18n/2008-March/msg00380.html
|
||||
* which discusses possible i18n concerns.
|
||||
*/
|
||||
static char*
|
||||
get_workspace_name_with_accel (Display *display,
|
||||
Window xroot,
|
||||
int index)
|
||||
{
|
||||
const char *name;
|
||||
int number;
|
||||
int charcount=0;
|
||||
|
||||
name = meta_core_get_workspace_name_with_index (display, xroot, index);
|
||||
|
||||
g_assert (name != NULL);
|
||||
|
||||
/*
|
||||
* If the name is of the form "Workspace x" where x is an unsigned
|
||||
* integer, insert a '_' before the number if it is less than 10 and
|
||||
* return it
|
||||
*/
|
||||
number = 0;
|
||||
if (sscanf (name, _("Workspace %d%n"), &number, &charcount) != 0 &&
|
||||
*(name + charcount)=='\0')
|
||||
{
|
||||
char *new_name;
|
||||
|
||||
/*
|
||||
* Above name is a pointer into the Workspace struct. Here we make
|
||||
* a copy copy so we can have our wicked way with it.
|
||||
*/
|
||||
if (number == 10)
|
||||
new_name = g_strdup_printf (_("Workspace 1_0"));
|
||||
else
|
||||
new_name = g_strdup_printf (_("Workspace %s%d"),
|
||||
number < 10 ? "_" : "",
|
||||
number);
|
||||
return new_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Otherwise this is just a normal name. Escape any _ characters so that
|
||||
* the user's workspace names do not get mangled. If the number is less
|
||||
* than 10 we provide an accelerator.
|
||||
*/
|
||||
char *new_name;
|
||||
const char *source;
|
||||
char *dest;
|
||||
|
||||
/*
|
||||
* Assume the worst case, that every character is a _. We also
|
||||
* provide memory for " (_#)"
|
||||
*/
|
||||
new_name = g_malloc0 (strlen (name) * 2 + 6 + 1);
|
||||
|
||||
/*
|
||||
* Now iterate down the strings, adding '_' to escape as we go
|
||||
*/
|
||||
dest = new_name;
|
||||
source = name;
|
||||
while (*source != '\0')
|
||||
{
|
||||
if (*source == '_')
|
||||
*dest++ = '_';
|
||||
*dest++ = *source++;
|
||||
}
|
||||
|
||||
/* People don't start at workspace 0, but workspace 1 */
|
||||
if (index < 9)
|
||||
{
|
||||
g_snprintf (dest, 6, " (_%d)", index + 1);
|
||||
}
|
||||
else if (index == 9)
|
||||
{
|
||||
g_snprintf (dest, 6, " (_0)");
|
||||
}
|
||||
|
||||
return new_name;
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
menu_item_new (MenuItem *menuitem, int workspace_id)
|
||||
{
|
||||
unsigned int key;
|
||||
MetaVirtualModifier mods;
|
||||
const char *i18n_label;
|
||||
GtkWidget *mi;
|
||||
GtkWidget *accel_label;
|
||||
|
||||
if (menuitem->type == MENU_ITEM_NORMAL)
|
||||
{
|
||||
mi = gtk_menu_item_new ();
|
||||
}
|
||||
else if (menuitem->type == MENU_ITEM_CHECKBOX)
|
||||
{
|
||||
mi = gtk_check_menu_item_new ();
|
||||
|
||||
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
|
||||
menuitem->checked);
|
||||
}
|
||||
else if (menuitem->type == MENU_ITEM_RADIOBUTTON)
|
||||
{
|
||||
mi = gtk_check_menu_item_new ();
|
||||
|
||||
gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (mi),
|
||||
TRUE);
|
||||
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
|
||||
menuitem->checked);
|
||||
}
|
||||
else if (menuitem->type == MENU_ITEM_WORKSPACE_LIST)
|
||||
return NULL;
|
||||
else
|
||||
return gtk_separator_menu_item_new ();
|
||||
|
||||
i18n_label = _(menuitem->label);
|
||||
meta_core_get_menu_accelerator (menuitem->op, workspace_id, &key, &mods);
|
||||
|
||||
accel_label = meta_accel_label_new_with_mnemonic (i18n_label);
|
||||
gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (mi), accel_label);
|
||||
gtk_widget_show (accel_label);
|
||||
|
||||
meta_accel_label_set_accelerator (META_ACCEL_LABEL (accel_label),
|
||||
key, mods);
|
||||
|
||||
return mi;
|
||||
}
|
||||
|
||||
MetaWindowMenu*
|
||||
meta_window_menu_new (MetaFrames *frames,
|
||||
MetaMenuOp ops,
|
||||
MetaMenuOp insensitive,
|
||||
Window client_xwindow,
|
||||
unsigned long active_workspace,
|
||||
int n_workspaces,
|
||||
MetaWindowMenuFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
int i;
|
||||
MetaWindowMenu *menu;
|
||||
|
||||
/* FIXME: Modifications to 'ops' should happen in meta_window_show_menu */
|
||||
if (n_workspaces < 2)
|
||||
ops &= ~(META_MENU_OP_STICK | META_MENU_OP_UNSTICK | META_MENU_OP_WORKSPACES);
|
||||
else if (n_workspaces == 2)
|
||||
/* #151183: If we only have two workspaces, disable the menu listing them. */
|
||||
ops &= ~(META_MENU_OP_WORKSPACES);
|
||||
|
||||
menu = g_new (MetaWindowMenu, 1);
|
||||
menu->frames = frames;
|
||||
menu->client_xwindow = client_xwindow;
|
||||
menu->func = func;
|
||||
menu->data = data;
|
||||
menu->ops = ops;
|
||||
menu->insensitive = insensitive;
|
||||
|
||||
menu->menu = gtk_menu_new ();
|
||||
|
||||
gtk_menu_set_screen (GTK_MENU (menu->menu),
|
||||
gtk_widget_get_screen (GTK_WIDGET (frames)));
|
||||
|
||||
for (i = 0; i < (int) G_N_ELEMENTS (menuitems); i++)
|
||||
{
|
||||
MenuItem menuitem = menuitems[i];
|
||||
if (ops & menuitem.op || menuitem.op == 0)
|
||||
{
|
||||
GtkWidget *mi;
|
||||
MenuData *md;
|
||||
unsigned int key;
|
||||
MetaVirtualModifier mods;
|
||||
|
||||
mi = menu_item_new (&menuitem, -1);
|
||||
|
||||
/* Set the activeness of radiobuttons. */
|
||||
switch (menuitem.op)
|
||||
{
|
||||
case META_MENU_OP_STICK:
|
||||
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
|
||||
active_workspace == 0xFFFFFFFF);
|
||||
break;
|
||||
case META_MENU_OP_UNSTICK:
|
||||
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
|
||||
active_workspace != 0xFFFFFFFF);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (menuitem.type == MENU_ITEM_WORKSPACE_LIST)
|
||||
{
|
||||
if (ops & META_MENU_OP_WORKSPACES)
|
||||
{
|
||||
Display *display;
|
||||
Window xroot;
|
||||
GdkScreen *screen;
|
||||
GdkWindow *window;
|
||||
GtkWidget *submenu;
|
||||
int j;
|
||||
|
||||
MenuItem to_another_workspace = {
|
||||
0, MENU_ITEM_NORMAL, FALSE,
|
||||
N_("Move to Another _Workspace")
|
||||
};
|
||||
|
||||
meta_verbose ("Creating %d-workspace menu current space %lu\n",
|
||||
n_workspaces, active_workspace);
|
||||
|
||||
window = gtk_widget_get_window (GTK_WIDGET (frames));
|
||||
display = GDK_WINDOW_XDISPLAY (window);
|
||||
|
||||
screen = gdk_window_get_screen (window);
|
||||
xroot = GDK_WINDOW_XID (gdk_screen_get_root_window (screen));
|
||||
|
||||
submenu = gtk_menu_new ();
|
||||
|
||||
g_assert (mi==NULL);
|
||||
mi = menu_item_new (&to_another_workspace, -1);
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), submenu);
|
||||
|
||||
for (j = 0; j < n_workspaces; j++)
|
||||
{
|
||||
char *label;
|
||||
MenuData *md;
|
||||
unsigned int key;
|
||||
MetaVirtualModifier mods;
|
||||
MenuItem moveitem;
|
||||
GtkWidget *submi;
|
||||
|
||||
meta_core_get_menu_accelerator (META_MENU_OP_WORKSPACES,
|
||||
j + 1,
|
||||
&key, &mods);
|
||||
|
||||
label = get_workspace_name_with_accel (display, xroot, j);
|
||||
|
||||
moveitem.type = MENU_ITEM_NORMAL;
|
||||
moveitem.op = META_MENU_OP_WORKSPACES;
|
||||
moveitem.label = label;
|
||||
submi = menu_item_new (&moveitem, j + 1);
|
||||
|
||||
g_free (label);
|
||||
|
||||
if ((active_workspace == (unsigned)j) && (ops & META_MENU_OP_UNSTICK))
|
||||
gtk_widget_set_sensitive (submi, FALSE);
|
||||
|
||||
md = g_new (MenuData, 1);
|
||||
|
||||
md->menu = menu;
|
||||
md->op = META_MENU_OP_WORKSPACES;
|
||||
|
||||
g_object_set_data (G_OBJECT (submi),
|
||||
"workspace",
|
||||
GINT_TO_POINTER (j));
|
||||
|
||||
g_signal_connect_data (G_OBJECT (submi),
|
||||
"activate",
|
||||
G_CALLBACK (activate_cb),
|
||||
md,
|
||||
(GClosureNotify) g_free, 0);
|
||||
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (submenu), submi);
|
||||
|
||||
gtk_widget_show (submi);
|
||||
}
|
||||
}
|
||||
else
|
||||
meta_verbose ("not creating workspace menu\n");
|
||||
}
|
||||
else if (menuitem.type != MENU_ITEM_SEPARATOR)
|
||||
{
|
||||
meta_core_get_menu_accelerator (menuitems[i].op, -1,
|
||||
&key, &mods);
|
||||
|
||||
if (insensitive & menuitem.op)
|
||||
gtk_widget_set_sensitive (mi, FALSE);
|
||||
|
||||
md = g_new (MenuData, 1);
|
||||
|
||||
md->menu = menu;
|
||||
md->op = menuitem.op;
|
||||
|
||||
g_signal_connect_data (G_OBJECT (mi),
|
||||
"activate",
|
||||
G_CALLBACK (activate_cb),
|
||||
md,
|
||||
(GClosureNotify) g_free, 0);
|
||||
}
|
||||
|
||||
if (mi)
|
||||
{
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu), mi);
|
||||
|
||||
gtk_widget_show (mi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
g_signal_connect (menu->menu, "selection_done",
|
||||
G_CALLBACK (menu_closed), menu);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_menu_popup (MetaWindowMenu *menu,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp)
|
||||
{
|
||||
GdkPoint *pt;
|
||||
|
||||
pt = g_new (GdkPoint, 1);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (menu->menu),
|
||||
"destroy-point",
|
||||
pt,
|
||||
g_free);
|
||||
|
||||
pt->x = root_x;
|
||||
pt->y = root_y;
|
||||
|
||||
gtk_menu_popup (GTK_MENU (menu->menu),
|
||||
NULL, NULL,
|
||||
popup_position_func, pt,
|
||||
button,
|
||||
timestamp);
|
||||
|
||||
if (!gtk_widget_get_visible (menu->menu))
|
||||
meta_warning ("GtkMenu failed to grab the pointer\n");
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_menu_free (MetaWindowMenu *menu)
|
||||
{
|
||||
gtk_widget_destroy (menu->menu);
|
||||
g_free (menu);
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Mutter window menu */
|
||||
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_MENU_H
|
||||
#define META_MENU_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "frames.h"
|
||||
|
||||
struct _MetaWindowMenu
|
||||
{
|
||||
MetaFrames *frames;
|
||||
Window client_xwindow;
|
||||
GtkWidget *menu;
|
||||
MetaWindowMenuFunc func;
|
||||
gpointer data;
|
||||
MetaMenuOp ops;
|
||||
MetaMenuOp insensitive;
|
||||
};
|
||||
|
||||
MetaWindowMenu* meta_window_menu_new (MetaFrames *frames,
|
||||
MetaMenuOp ops,
|
||||
MetaMenuOp insensitive,
|
||||
Window client_xwindow,
|
||||
unsigned long active_workspace,
|
||||
int n_workspaces,
|
||||
MetaWindowMenuFunc func,
|
||||
gpointer data);
|
||||
void meta_window_menu_popup (MetaWindowMenu *menu,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp);
|
||||
void meta_window_menu_free (MetaWindowMenu *menu);
|
||||
|
||||
|
||||
#endif
|
@ -1,315 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Mutter gradient test program */
|
||||
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <meta/gradient.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
typedef void (* RenderGradientFunc) (cairo_t *cr,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
static void
|
||||
draw_checkerboard (cairo_t *cr,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
gint i, j, xcount, ycount;
|
||||
GdkRGBA color1, color2;
|
||||
|
||||
#define CHECK_SIZE 10
|
||||
#define SPACING 2
|
||||
|
||||
color1.red = 30000. / 65535.;
|
||||
color1.green = 30000. / 65535.;
|
||||
color1.blue = 30000. / 65535.;
|
||||
color1.alpha = 1.0;
|
||||
|
||||
color2.red = 50000. / 65535.;
|
||||
color2.green = 50000. / 65535.;
|
||||
color2.blue = 50000. / 65535.;
|
||||
color2.alpha = 1.0;
|
||||
|
||||
xcount = 0;
|
||||
i = SPACING;
|
||||
while (i < width)
|
||||
{
|
||||
j = SPACING;
|
||||
ycount = xcount % 2; /* start with even/odd depending on row */
|
||||
while (j < height)
|
||||
{
|
||||
if (ycount % 2)
|
||||
gdk_cairo_set_source_rgba (cr, &color1);
|
||||
else
|
||||
gdk_cairo_set_source_rgba (cr, &color2);
|
||||
|
||||
/* If we're outside event->area, this will do nothing.
|
||||
* It might be mildly more efficient if we handled
|
||||
* the clipping ourselves, but again we're feeling lazy.
|
||||
*/
|
||||
cairo_rectangle (cr, i, j, CHECK_SIZE, CHECK_SIZE);
|
||||
cairo_fill (cr);
|
||||
|
||||
j += CHECK_SIZE + SPACING;
|
||||
++ycount;
|
||||
}
|
||||
|
||||
i += CHECK_SIZE + SPACING;
|
||||
++xcount;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
render_simple (cairo_t *cr,
|
||||
int width, int height,
|
||||
MetaGradientType type,
|
||||
gboolean with_alpha)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkRGBA from, to;
|
||||
|
||||
gdk_rgba_parse (&from, "blue");
|
||||
gdk_rgba_parse (&to, "green");
|
||||
|
||||
pixbuf = meta_gradient_create_simple (width, height,
|
||||
&from, &to,
|
||||
type);
|
||||
|
||||
if (with_alpha)
|
||||
{
|
||||
const unsigned char alphas[] = { 0xff, 0xaa, 0x2f, 0x0, 0xcc, 0xff, 0xff };
|
||||
|
||||
if (!gdk_pixbuf_get_has_alpha (pixbuf))
|
||||
{
|
||||
GdkPixbuf *new_pixbuf;
|
||||
|
||||
new_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
pixbuf = new_pixbuf;
|
||||
}
|
||||
|
||||
meta_gradient_add_alpha (pixbuf,
|
||||
alphas, G_N_ELEMENTS (alphas),
|
||||
META_GRADIENT_HORIZONTAL);
|
||||
|
||||
draw_checkerboard (cr , width, height);
|
||||
}
|
||||
|
||||
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
||||
cairo_rectangle (cr, 0, 0, width, height);
|
||||
cairo_fill (cr);
|
||||
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
}
|
||||
|
||||
static void
|
||||
render_vertical_func (cairo_t *cr,
|
||||
int width, int height)
|
||||
{
|
||||
render_simple (cr, width, height, META_GRADIENT_VERTICAL, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
render_horizontal_func (cairo_t *cr,
|
||||
int width, int height)
|
||||
{
|
||||
render_simple (cr, width, height, META_GRADIENT_HORIZONTAL, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
render_diagonal_func (cairo_t *cr,
|
||||
int width, int height)
|
||||
{
|
||||
render_simple (cr, width, height, META_GRADIENT_DIAGONAL, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
render_diagonal_alpha_func (cairo_t *cr,
|
||||
int width, int height)
|
||||
{
|
||||
render_simple (cr, width, height, META_GRADIENT_DIAGONAL, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
render_multi (cairo_t *cr,
|
||||
int width, int height,
|
||||
MetaGradientType type)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
#define N_COLORS 5
|
||||
GdkRGBA colors[N_COLORS];
|
||||
|
||||
gdk_rgba_parse (&colors[0], "red");
|
||||
gdk_rgba_parse (&colors[1], "blue");
|
||||
gdk_rgba_parse (&colors[2], "orange");
|
||||
gdk_rgba_parse (&colors[3], "pink");
|
||||
gdk_rgba_parse (&colors[4], "green");
|
||||
|
||||
pixbuf = meta_gradient_create_multi (width, height,
|
||||
colors, N_COLORS,
|
||||
type);
|
||||
|
||||
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
||||
cairo_rectangle (cr, 0, 0, width, height);
|
||||
cairo_fill (cr);
|
||||
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
#undef N_COLORS
|
||||
}
|
||||
|
||||
static void
|
||||
render_vertical_multi_func (cairo_t *cr,
|
||||
int width, int height)
|
||||
{
|
||||
render_multi (cr, width, height, META_GRADIENT_VERTICAL);
|
||||
}
|
||||
|
||||
static void
|
||||
render_horizontal_multi_func (cairo_t *cr,
|
||||
int width, int height)
|
||||
{
|
||||
render_multi (cr, width, height, META_GRADIENT_HORIZONTAL);
|
||||
}
|
||||
|
||||
static void
|
||||
render_diagonal_multi_func (cairo_t *cr,
|
||||
int width, int height)
|
||||
{
|
||||
render_multi (cr, width, height, META_GRADIENT_DIAGONAL);
|
||||
}
|
||||
|
||||
static void
|
||||
render_interwoven_func (cairo_t *cr,
|
||||
int width, int height)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
#define N_COLORS 4
|
||||
GdkRGBA colors[N_COLORS];
|
||||
|
||||
gdk_rgba_parse (&colors[0], "red");
|
||||
gdk_rgba_parse (&colors[1], "blue");
|
||||
gdk_rgba_parse (&colors[2], "pink");
|
||||
gdk_rgba_parse (&colors[3], "green");
|
||||
|
||||
pixbuf = meta_gradient_create_interwoven (width, height,
|
||||
colors, height / 10,
|
||||
colors + 2, height / 14);
|
||||
|
||||
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
||||
cairo_rectangle (cr, 0, 0, width, height);
|
||||
cairo_fill (cr);
|
||||
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
draw_callback (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
gpointer data)
|
||||
{
|
||||
RenderGradientFunc func = data;
|
||||
GtkStyleContext *style;
|
||||
GdkRGBA color;
|
||||
|
||||
style = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_style_context_save (style);
|
||||
gtk_style_context_set_state (style, gtk_widget_get_state_flags (widget));
|
||||
gtk_style_context_lookup_color (style, "foreground-color", &color);
|
||||
gtk_style_context_restore (style);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, &color);
|
||||
|
||||
(* func) (cr,
|
||||
gtk_widget_get_allocated_width (widget),
|
||||
gtk_widget_get_allocated_height (widget));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
create_gradient_window (const char *title,
|
||||
RenderGradientFunc func)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *drawing_area;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (window), title);
|
||||
|
||||
drawing_area = gtk_drawing_area_new ();
|
||||
|
||||
gtk_widget_set_size_request (drawing_area, 1, 1);
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 175, 175);
|
||||
|
||||
g_signal_connect (G_OBJECT (drawing_area),
|
||||
"draw",
|
||||
G_CALLBACK (draw_callback),
|
||||
func);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (window), drawing_area);
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_gradient_test (void)
|
||||
{
|
||||
create_gradient_window ("Simple vertical",
|
||||
render_vertical_func);
|
||||
|
||||
create_gradient_window ("Simple horizontal",
|
||||
render_horizontal_func);
|
||||
|
||||
create_gradient_window ("Simple diagonal",
|
||||
render_diagonal_func);
|
||||
|
||||
create_gradient_window ("Multi vertical",
|
||||
render_vertical_multi_func);
|
||||
|
||||
create_gradient_window ("Multi horizontal",
|
||||
render_horizontal_multi_func);
|
||||
|
||||
create_gradient_window ("Multi diagonal",
|
||||
render_diagonal_multi_func);
|
||||
|
||||
create_gradient_window ("Interwoven",
|
||||
render_interwoven_func);
|
||||
|
||||
create_gradient_window ("Simple diagonal with horizontal multi alpha",
|
||||
render_diagonal_alpha_func);
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
meta_gradient_test ();
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
6802
src/ui/theme.c
6802
src/ui/theme.c
File diff suppressed because it is too large
Load Diff
446
src/ui/ui.c
446
src/ui/ui.c
@ -22,11 +22,8 @@
|
||||
#include <config.h>
|
||||
#include <meta/prefs.h>
|
||||
#include "ui.h"
|
||||
#include "frames.h"
|
||||
#include <meta/util.h>
|
||||
#include "menu.h"
|
||||
#include "core.h"
|
||||
#include "theme-private.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -41,7 +38,6 @@ struct _MetaUI
|
||||
{
|
||||
Display *xdisplay;
|
||||
Screen *xscreen;
|
||||
MetaFrames *frames;
|
||||
|
||||
/* For double-click tracking */
|
||||
gint button_click_number;
|
||||
@ -56,11 +52,6 @@ meta_ui_init (void)
|
||||
{
|
||||
if (!gtk_init_check (NULL, NULL))
|
||||
meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL));
|
||||
|
||||
/* We need to be able to fully trust that the window and monitor sizes
|
||||
that Gdk reports corresponds to the X ones, so we disable the automatic
|
||||
scale handling */
|
||||
gdk_x11_display_set_window_scale (gdk_display_get_default (), 1);
|
||||
}
|
||||
|
||||
Display*
|
||||
@ -75,162 +66,6 @@ meta_ui_get_screen_number (void)
|
||||
return gdk_screen_get_number (gdk_screen_get_default ());
|
||||
}
|
||||
|
||||
/* For XInput2 */
|
||||
#include "display-private.h"
|
||||
|
||||
static gboolean
|
||||
is_input_event (XEvent *event)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
return (event->type == GenericEvent &&
|
||||
event->xcookie.extension == display->xinput_opcode);
|
||||
}
|
||||
|
||||
/* We do some of our event handling in frames.c, which expects
|
||||
* GDK events delivered by GTK+. However, since the transition to
|
||||
* client side windows, we can't let GDK see button events, since the
|
||||
* client-side tracking of implicit and explicit grabs it does will
|
||||
* get confused by our direct use of X grabs in the core code.
|
||||
*
|
||||
* So we do a very minimal GDK => GTK event conversion here and send on the
|
||||
* events we care about, and then filter them out so they don't go
|
||||
* through the normal GDK event handling.
|
||||
*
|
||||
* To reduce the amount of code, the only events fields filled out
|
||||
* below are the ones that frames.c uses. If frames.c is modified to
|
||||
* use more fields, more fields need to be filled out below.
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
maybe_redirect_mouse_event (XEvent *xevent)
|
||||
{
|
||||
GdkDisplay *gdisplay;
|
||||
GdkDeviceManager *gmanager;
|
||||
GdkDevice *gdevice;
|
||||
MetaUI *ui;
|
||||
GdkEvent *gevent;
|
||||
GdkWindow *gdk_window;
|
||||
Window window;
|
||||
XIEvent *xev;
|
||||
XIDeviceEvent *xev_d = NULL;
|
||||
XIEnterEvent *xev_e = NULL;
|
||||
|
||||
if (!is_input_event (xevent))
|
||||
return FALSE;
|
||||
|
||||
xev = (XIEvent *) xevent->xcookie.data;
|
||||
|
||||
switch (xev->evtype)
|
||||
{
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
case XI_Motion:
|
||||
xev_d = (XIDeviceEvent *) xev;
|
||||
window = xev_d->event;
|
||||
break;
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
xev_e = (XIEnterEvent *) xev;
|
||||
window = xev_e->event;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdisplay = gdk_x11_lookup_xdisplay (xev->display);
|
||||
ui = g_object_get_data (G_OBJECT (gdisplay), "meta-ui");
|
||||
if (!ui)
|
||||
return FALSE;
|
||||
|
||||
gdk_window = gdk_x11_window_lookup_for_display (gdisplay, window);
|
||||
if (gdk_window == NULL)
|
||||
return FALSE;
|
||||
|
||||
gmanager = gdk_display_get_device_manager (gdisplay);
|
||||
gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);
|
||||
|
||||
/* If GDK already thinks it has a grab, we better let it see events; this
|
||||
* is the menu-navigation case and events need to get sent to the appropriate
|
||||
* (client-side) subwindow for individual menu items.
|
||||
*/
|
||||
if (gdk_display_device_is_grabbed (gdisplay, gdevice))
|
||||
return FALSE;
|
||||
|
||||
switch (xev->evtype)
|
||||
{
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
if (xev_d->evtype == XI_ButtonPress)
|
||||
{
|
||||
GtkSettings *settings = gtk_settings_get_default ();
|
||||
int double_click_time;
|
||||
int double_click_distance;
|
||||
|
||||
g_object_get (settings,
|
||||
"gtk-double-click-time", &double_click_time,
|
||||
"gtk-double-click-distance", &double_click_distance,
|
||||
NULL);
|
||||
|
||||
if (xev_d->detail == ui->button_click_number &&
|
||||
xev_d->event == ui->button_click_window &&
|
||||
xev_d->time < ui->button_click_time + double_click_time &&
|
||||
ABS (xev_d->event_x - ui->button_click_x) <= double_click_distance &&
|
||||
ABS (xev_d->event_y - ui->button_click_y) <= double_click_distance)
|
||||
{
|
||||
gevent = gdk_event_new (GDK_2BUTTON_PRESS);
|
||||
|
||||
ui->button_click_number = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gevent = gdk_event_new (GDK_BUTTON_PRESS);
|
||||
ui->button_click_number = xev_d->detail;
|
||||
ui->button_click_window = xev_d->event;
|
||||
ui->button_click_time = xev_d->time;
|
||||
ui->button_click_x = xev_d->event_x;
|
||||
ui->button_click_y = xev_d->event_y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gevent = gdk_event_new (GDK_BUTTON_RELEASE);
|
||||
}
|
||||
|
||||
gevent->button.window = g_object_ref (gdk_window);
|
||||
gevent->button.button = xev_d->detail;
|
||||
gevent->button.time = xev_d->time;
|
||||
gevent->button.x = xev_d->event_x;
|
||||
gevent->button.y = xev_d->event_y;
|
||||
gevent->button.x_root = xev_d->root_x;
|
||||
gevent->button.y_root = xev_d->root_y;
|
||||
|
||||
break;
|
||||
case XI_Motion:
|
||||
gevent = gdk_event_new (GDK_MOTION_NOTIFY);
|
||||
gevent->motion.type = GDK_MOTION_NOTIFY;
|
||||
gevent->motion.window = g_object_ref (gdk_window);
|
||||
break;
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
gevent = gdk_event_new (xev_e->evtype == XI_Enter ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY);
|
||||
gevent->crossing.window = g_object_ref (gdk_window);
|
||||
gevent->crossing.x = xev_e->event_x;
|
||||
gevent->crossing.y = xev_e->event_y;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we've gotten here, we've created the gdk_event and should send it on */
|
||||
gdk_event_set_device (gevent, gdevice);
|
||||
gtk_main_do_event (gevent);
|
||||
gdk_event_free (gevent);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct _EventFunc EventFunc;
|
||||
|
||||
struct _EventFunc
|
||||
@ -248,8 +83,7 @@ filter_func (GdkXEvent *xevent,
|
||||
{
|
||||
g_return_val_if_fail (ef != NULL, GDK_FILTER_CONTINUE);
|
||||
|
||||
if ((* ef->func) (xevent, ef->data) ||
|
||||
maybe_redirect_mouse_event (xevent))
|
||||
if ((* ef->func) (xevent, ef->data))
|
||||
return GDK_FILTER_REMOVE;
|
||||
else
|
||||
return GDK_FILTER_CONTINUE;
|
||||
@ -297,12 +131,6 @@ meta_ui_new (Display *xdisplay,
|
||||
gdisplay = gdk_x11_lookup_xdisplay (xdisplay);
|
||||
g_assert (gdisplay == gdk_display_get_default ());
|
||||
|
||||
ui->frames = meta_frames_new (XScreenNumberOfScreen (screen));
|
||||
/* This does not actually show any widget. MetaFrames has been hacked so
|
||||
* that showing it doesn't actually do anything. But we need the flags
|
||||
* set for GTK to deliver events properly. */
|
||||
gtk_widget_show (GTK_WIDGET (ui->frames));
|
||||
|
||||
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui);
|
||||
|
||||
return ui;
|
||||
@ -313,33 +141,12 @@ meta_ui_free (MetaUI *ui)
|
||||
{
|
||||
GdkDisplay *gdisplay;
|
||||
|
||||
gtk_widget_destroy (GTK_WIDGET (ui->frames));
|
||||
|
||||
gdisplay = gdk_x11_lookup_xdisplay (ui->xdisplay);
|
||||
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", NULL);
|
||||
|
||||
g_free (ui);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_get_frame_mask (MetaUI *ui,
|
||||
Window frame_xwindow,
|
||||
guint width,
|
||||
guint height,
|
||||
cairo_t *cr)
|
||||
{
|
||||
meta_frames_get_mask (ui->frames, frame_xwindow, width, height, cr);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_get_frame_borders (MetaUI *ui,
|
||||
Window frame_xwindow,
|
||||
MetaFrameBorders *borders)
|
||||
{
|
||||
meta_frames_get_borders (ui->frames, frame_xwindow,
|
||||
borders);
|
||||
}
|
||||
|
||||
Window
|
||||
meta_ui_create_frame_window (MetaUI *ui,
|
||||
Display *xdisplay,
|
||||
@ -351,72 +158,13 @@ meta_ui_create_frame_window (MetaUI *ui,
|
||||
gint screen_no,
|
||||
gulong *create_serial)
|
||||
{
|
||||
GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
|
||||
GdkScreen *screen = gdk_display_get_screen (display, screen_no);
|
||||
GdkWindowAttr attrs;
|
||||
gint attributes_mask;
|
||||
GdkWindow *window;
|
||||
GdkVisual *visual;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* frame.c is going to replace the event mask immediately, but
|
||||
* we still have to set it here to let GDK know what it is.
|
||||
*/
|
||||
attrs.event_mask =
|
||||
GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
|
||||
GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_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);
|
||||
|
||||
meta_frames_manage_window (ui->frames, GDK_WINDOW_XID (window), window);
|
||||
|
||||
return GDK_WINDOW_XID (window);
|
||||
return None;
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_destroy_frame_window (MetaUI *ui,
|
||||
Window xwindow)
|
||||
{
|
||||
meta_frames_unmanage_window (ui->frames, xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
@ -427,83 +175,6 @@ meta_ui_move_resize_frame (MetaUI *ui,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
meta_frames_move_resize_frame (ui->frames, frame, x, y, width, height);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_unflicker_frame_bg (MetaUI *ui,
|
||||
Window xwindow,
|
||||
int target_width,
|
||||
int target_height)
|
||||
{
|
||||
meta_frames_unflicker_bg (ui->frames, xwindow,
|
||||
target_width, target_height);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_update_frame_style (MetaUI *ui,
|
||||
Window xwindow)
|
||||
{
|
||||
meta_frames_update_frame_style (ui->frames, xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_repaint_frame (MetaUI *ui,
|
||||
Window xwindow)
|
||||
{
|
||||
meta_frames_repaint_frame (ui->frames, xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_reset_frame_bg (MetaUI *ui,
|
||||
Window xwindow)
|
||||
{
|
||||
meta_frames_reset_bg (ui->frames, xwindow);
|
||||
}
|
||||
|
||||
cairo_region_t *
|
||||
meta_ui_get_frame_bounds (MetaUI *ui,
|
||||
Window xwindow,
|
||||
int window_width,
|
||||
int window_height)
|
||||
{
|
||||
return meta_frames_get_frame_bounds (ui->frames, xwindow,
|
||||
window_width, window_height);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_queue_frame_draw (MetaUI *ui,
|
||||
Window xwindow)
|
||||
{
|
||||
meta_frames_queue_draw (ui->frames, xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
@ -511,41 +182,12 @@ meta_ui_set_frame_title (MetaUI *ui,
|
||||
Window xwindow,
|
||||
const char *title)
|
||||
{
|
||||
meta_frames_set_title (ui->frames, xwindow, title);
|
||||
}
|
||||
|
||||
MetaWindowMenu*
|
||||
meta_ui_window_menu_new (MetaUI *ui,
|
||||
Window client_xwindow,
|
||||
MetaMenuOp ops,
|
||||
MetaMenuOp insensitive,
|
||||
unsigned long active_workspace,
|
||||
int n_workspaces,
|
||||
MetaWindowMenuFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
return meta_window_menu_new (ui->frames,
|
||||
ops, insensitive,
|
||||
client_xwindow,
|
||||
active_workspace,
|
||||
n_workspaces,
|
||||
func, data);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_window_menu_popup (MetaWindowMenu *menu,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp)
|
||||
meta_ui_update_frame_style (MetaUI *ui,
|
||||
Window xwindow)
|
||||
{
|
||||
meta_window_menu_popup (menu, root_x, root_y, button, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_window_menu_free (MetaWindowMenu *menu)
|
||||
{
|
||||
meta_window_menu_free (menu);
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
@ -725,63 +367,7 @@ meta_ui_theme_get_frame_borders (MetaUI *ui,
|
||||
MetaFrameFlags flags,
|
||||
MetaFrameBorders *borders)
|
||||
{
|
||||
int text_height;
|
||||
GtkStyleContext *style = NULL;
|
||||
PangoContext *context;
|
||||
const PangoFontDescription *font_desc;
|
||||
PangoFontDescription *free_font_desc = NULL;
|
||||
|
||||
if (meta_ui_have_a_theme ())
|
||||
{
|
||||
context = gtk_widget_get_pango_context (GTK_WIDGET (ui->frames));
|
||||
font_desc = meta_prefs_get_titlebar_font ();
|
||||
|
||||
if (!font_desc)
|
||||
{
|
||||
GdkDisplay *display = gdk_x11_lookup_xdisplay (ui->xdisplay);
|
||||
GdkScreen *screen = gdk_display_get_screen (display, XScreenNumberOfScreen (ui->xscreen));
|
||||
GtkWidgetPath *widget_path;
|
||||
|
||||
style = gtk_style_context_new ();
|
||||
gtk_style_context_set_screen (style, screen);
|
||||
widget_path = gtk_widget_path_new ();
|
||||
gtk_widget_path_append_type (widget_path, GTK_TYPE_WINDOW);
|
||||
gtk_style_context_set_path (style, widget_path);
|
||||
gtk_widget_path_free (widget_path);
|
||||
|
||||
gtk_style_context_get (style, GTK_STATE_FLAG_NORMAL, "font", &free_font_desc, NULL);
|
||||
font_desc = (const PangoFontDescription *) free_font_desc;
|
||||
}
|
||||
|
||||
text_height = meta_pango_font_desc_get_text_height (font_desc, context);
|
||||
|
||||
meta_theme_get_frame_borders (meta_theme_get_current (),
|
||||
type, text_height, flags,
|
||||
borders);
|
||||
|
||||
if (free_font_desc)
|
||||
pango_font_description_free (free_font_desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_frame_borders_clear (borders);
|
||||
}
|
||||
|
||||
if (style != NULL)
|
||||
g_object_unref (style);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_set_current_theme (const char *name)
|
||||
{
|
||||
meta_theme_set_current (name);
|
||||
meta_invalidate_default_icons ();
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_ui_have_a_theme (void)
|
||||
{
|
||||
return meta_theme_get_current () != NULL;
|
||||
meta_frame_borders_clear (borders);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -974,33 +560,13 @@ meta_ui_parse_modifier (const char *accel,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
meta_ui_get_drag_threshold (MetaUI *ui)
|
||||
{
|
||||
GtkSettings *settings;
|
||||
int threshold;
|
||||
|
||||
settings = gtk_widget_get_settings (GTK_WIDGET (ui->frames));
|
||||
settings = gtk_settings_get_default ();
|
||||
|
||||
threshold = 8;
|
||||
g_object_get (G_OBJECT (settings), "gtk-dnd-drag-threshold", &threshold, NULL);
|
||||
|
57
src/ui/ui.h
57
src/ui/ui.h
@ -61,16 +61,6 @@ void meta_ui_theme_get_frame_borders (MetaUI *ui,
|
||||
MetaFrameType type,
|
||||
MetaFrameFlags flags,
|
||||
MetaFrameBorders *borders);
|
||||
void meta_ui_get_frame_borders (MetaUI *ui,
|
||||
Window frame_xwindow,
|
||||
MetaFrameBorders *borders);
|
||||
|
||||
void meta_ui_get_frame_mask (MetaUI *ui,
|
||||
Window frame_xwindow,
|
||||
guint width,
|
||||
guint height,
|
||||
cairo_t *cr);
|
||||
|
||||
Window meta_ui_create_frame_window (MetaUI *ui,
|
||||
Display *xdisplay,
|
||||
Visual *xvisual,
|
||||
@ -88,54 +78,12 @@ void meta_ui_move_resize_frame (MetaUI *ui,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
/* GDK insists on tracking map/unmap */
|
||||
void meta_ui_map_frame (MetaUI *ui,
|
||||
Window xwindow);
|
||||
void meta_ui_unmap_frame (MetaUI *ui,
|
||||
Window xwindow);
|
||||
|
||||
void meta_ui_unflicker_frame_bg (MetaUI *ui,
|
||||
Window xwindow,
|
||||
int target_width,
|
||||
int target_height);
|
||||
void meta_ui_reset_frame_bg (MetaUI *ui,
|
||||
Window xwindow);
|
||||
|
||||
cairo_region_t *meta_ui_get_frame_bounds (MetaUI *ui,
|
||||
Window xwindow,
|
||||
int window_width,
|
||||
int window_height);
|
||||
|
||||
void meta_ui_queue_frame_draw (MetaUI *ui,
|
||||
Window xwindow);
|
||||
|
||||
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,
|
||||
Window client_xwindow,
|
||||
MetaMenuOp ops,
|
||||
MetaMenuOp insensitive,
|
||||
unsigned long active_workspace,
|
||||
int n_workspaces,
|
||||
MetaWindowMenuFunc func,
|
||||
gpointer data);
|
||||
void meta_ui_window_menu_popup (MetaWindowMenu *menu,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp);
|
||||
void meta_ui_window_menu_free (MetaWindowMenu *menu);
|
||||
|
||||
|
||||
/* FIXME these lack a display arg */
|
||||
GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
|
||||
int src_x,
|
||||
@ -152,9 +100,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 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
|
||||
@ -171,8 +116,6 @@ gboolean meta_ui_parse_modifier (const char *accel,
|
||||
/* Caller responsible for freeing return string of meta_ui_accelerator_name! */
|
||||
gchar* meta_ui_accelerator_name (unsigned int keysym,
|
||||
MetaVirtualModifier mask);
|
||||
gboolean meta_ui_window_is_widget (MetaUI *ui,
|
||||
Window xwindow);
|
||||
|
||||
int meta_ui_get_drag_threshold (MetaUI *ui);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user