Compare commits
2 Commits
wip/carlos
...
wip/no-rep
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2ff2a27229 | ||
![]() |
9c362f7fe4 |
@@ -94,8 +94,6 @@ libmutter_la_SOURCES = \
|
|||||||
core/display.c \
|
core/display.c \
|
||||||
core/display-private.h \
|
core/display-private.h \
|
||||||
meta/display.h \
|
meta/display.h \
|
||||||
ui/draw-workspace.c \
|
|
||||||
ui/draw-workspace.h \
|
|
||||||
core/edge-resistance.c \
|
core/edge-resistance.c \
|
||||||
core/edge-resistance.h \
|
core/edge-resistance.h \
|
||||||
core/edid-parse.c \
|
core/edid-parse.c \
|
||||||
@@ -104,8 +102,6 @@ libmutter_la_SOURCES = \
|
|||||||
meta/errors.h \
|
meta/errors.h \
|
||||||
core/frame.c \
|
core/frame.c \
|
||||||
core/frame.h \
|
core/frame.h \
|
||||||
ui/gradient.c \
|
|
||||||
meta/gradient.h \
|
|
||||||
core/group-private.h \
|
core/group-private.h \
|
||||||
core/group-props.c \
|
core/group-props.c \
|
||||||
core/group-props.h \
|
core/group-props.h \
|
||||||
@@ -154,22 +150,12 @@ libmutter_la_SOURCES = \
|
|||||||
core/xprops.h \
|
core/xprops.h \
|
||||||
meta/common.h \
|
meta/common.h \
|
||||||
core/core.h \
|
core/core.h \
|
||||||
|
ui/ui.c \
|
||||||
ui/ui.h \
|
ui/ui.h \
|
||||||
ui/frames.c \
|
|
||||||
ui/frames.h \
|
|
||||||
ui/menu.c \
|
|
||||||
ui/menu.h \
|
|
||||||
ui/metaaccellabel.c \
|
ui/metaaccellabel.c \
|
||||||
ui/metaaccellabel.h \
|
ui/metaaccellabel.h \
|
||||||
ui/resizepopup.c \
|
ui/resizepopup.c \
|
||||||
ui/resizepopup.h \
|
ui/resizepopup.h
|
||||||
ui/tabpopup.c \
|
|
||||||
ui/tabpopup.h \
|
|
||||||
ui/theme-parser.c \
|
|
||||||
ui/theme.c \
|
|
||||||
meta/theme.h \
|
|
||||||
ui/theme-private.h \
|
|
||||||
ui/ui.c
|
|
||||||
|
|
||||||
nodist_libmutter_la_SOURCES = \
|
nodist_libmutter_la_SOURCES = \
|
||||||
$(mutter_built_sources)
|
$(mutter_built_sources)
|
||||||
@@ -187,7 +173,6 @@ libmutterinclude_base_headers = \
|
|||||||
meta/compositor.h \
|
meta/compositor.h \
|
||||||
meta/display.h \
|
meta/display.h \
|
||||||
meta/errors.h \
|
meta/errors.h \
|
||||||
meta/gradient.h \
|
|
||||||
meta/group.h \
|
meta/group.h \
|
||||||
meta/keybindings.h \
|
meta/keybindings.h \
|
||||||
meta/main.h \
|
meta/main.h \
|
||||||
@@ -202,7 +187,6 @@ libmutterinclude_base_headers = \
|
|||||||
meta/meta-window-actor.h \
|
meta/meta-window-actor.h \
|
||||||
meta/prefs.h \
|
meta/prefs.h \
|
||||||
meta/screen.h \
|
meta/screen.h \
|
||||||
meta/theme.h \
|
|
||||||
meta/types.h \
|
meta/types.h \
|
||||||
meta/util.h \
|
meta/util.h \
|
||||||
meta/window.h \
|
meta/window.h \
|
||||||
@@ -258,13 +242,11 @@ Meta-$(api_version).gir: libmutter.la
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
testboxes_SOURCES = core/testboxes.c
|
testboxes_SOURCES = core/testboxes.c
|
||||||
testgradient_SOURCES = ui/testgradient.c
|
|
||||||
testasyncgetprop_SOURCES = core/testasyncgetprop.c
|
testasyncgetprop_SOURCES = core/testasyncgetprop.c
|
||||||
|
|
||||||
noinst_PROGRAMS=testboxes testgradient testasyncgetprop
|
noinst_PROGRAMS=testboxes testasyncgetprop
|
||||||
|
|
||||||
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
|
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||||
testgradient_LDADD = $(MUTTER_LIBS) libmutter.la
|
|
||||||
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la
|
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||||
|
|
||||||
@INTLTOOL_DESKTOP_RULE@
|
@INTLTOOL_DESKTOP_RULE@
|
||||||
|
@@ -361,6 +361,7 @@ meta_window_actor_dispose (GObject *object)
|
|||||||
xdisplay = meta_display_get_xdisplay (display);
|
xdisplay = meta_display_get_xdisplay (display);
|
||||||
info = meta_screen_get_compositor_data (screen);
|
info = meta_screen_get_compositor_data (screen);
|
||||||
|
|
||||||
|
meta_window_actor_set_redirected (self, FALSE);
|
||||||
meta_window_actor_detach (self);
|
meta_window_actor_detach (self);
|
||||||
|
|
||||||
if (priv->send_frame_messages_timer != 0)
|
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 *
|
static const char *
|
||||||
meta_window_actor_get_shadow_class (MetaWindowActor *self)
|
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
|
static void
|
||||||
build_and_scan_frame_mask (MetaWindowActor *self,
|
build_and_scan_frame_mask (MetaWindowActor *self,
|
||||||
cairo_rectangle_int_t *client_area,
|
cairo_rectangle_int_t *client_area,
|
||||||
@@ -1914,27 +1908,6 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
|||||||
gdk_cairo_region (cr, shape_region);
|
gdk_cairo_region (cr, shape_region);
|
||||||
cairo_fill (cr);
|
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_destroy (cr);
|
||||||
cairo_surface_destroy (surface);
|
cairo_surface_destroy (surface);
|
||||||
|
|
||||||
|
@@ -4176,20 +4176,6 @@ meta_display_end_grab_op (MetaDisplay *display,
|
|||||||
meta_window_raise (display->grab_window);
|
meta_window_raise (display->grab_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op) ||
|
|
||||||
display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING)
|
|
||||||
{
|
|
||||||
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
|
|
||||||
meta_screen_tab_popup_destroy (display->grab_screen);
|
|
||||||
else
|
|
||||||
meta_screen_workspace_popup_destroy (display->grab_screen);
|
|
||||||
|
|
||||||
/* If the ungrab here causes an EnterNotify, ignore it for
|
|
||||||
* sloppy focus
|
|
||||||
*/
|
|
||||||
display->ungrab_should_not_cause_focus_window = display->grab_xwindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If this was a move or resize clear out the edge cache */
|
/* If this was a move or resize clear out the edge cache */
|
||||||
if (meta_grab_op_is_resizing (display->grab_op) ||
|
if (meta_grab_op_is_resizing (display->grab_op) ||
|
||||||
meta_grab_op_is_moving (display->grab_op))
|
meta_grab_op_is_moving (display->grab_op))
|
||||||
|
137
src/core/frame.c
137
src/core/frame.c
@@ -43,7 +43,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
{
|
{
|
||||||
MetaFrame *frame;
|
MetaFrame *frame;
|
||||||
XSetWindowAttributes attrs;
|
XSetWindowAttributes attrs;
|
||||||
Visual *visual;
|
|
||||||
gulong create_serial;
|
gulong create_serial;
|
||||||
|
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
@@ -62,52 +61,33 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
frame->current_cursor = 0;
|
frame->current_cursor = 0;
|
||||||
|
|
||||||
frame->is_flashing = FALSE;
|
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",
|
meta_verbose ("Frame geometry %d,%d %dx%d\n",
|
||||||
frame->rect.x, frame->rect.y,
|
frame->rect.x, frame->rect.y,
|
||||||
frame->rect.width, frame->rect.height);
|
frame->rect.width, frame->rect.height);
|
||||||
|
|
||||||
/* Default depth/visual handles clients with weird visuals; they can
|
attrs.event_mask = EVENT_MASK;
|
||||||
* always be children of the root depth/visual obviously, but
|
XChangeWindowAttributes (window->display->xdisplay,
|
||||||
* e.g. DRI games can't be children of a parent that has the same
|
frame->xwindow, CWEventMask, &attrs);
|
||||||
* 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),
|
create_serial = XNextRequest (window->display->xdisplay);
|
||||||
* we use the window's visual. Otherwise we just use the system visual.
|
|
||||||
*/
|
frame->xwindow = XCreateWindow (window->display->xdisplay,
|
||||||
if (window->depth == 32)
|
DefaultRootWindow (window->display->xdisplay),
|
||||||
visual = window->xvisual;
|
frame->rect.x, frame->rect.y,
|
||||||
else
|
frame->rect.width, frame->rect.height,
|
||||||
visual = NULL;
|
0,
|
||||||
|
CopyFromParent,
|
||||||
|
InputOnly,
|
||||||
|
CopyFromParent,
|
||||||
|
CWEventMask,
|
||||||
|
&attrs);
|
||||||
|
|
||||||
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);
|
|
||||||
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
||||||
frame->xwindow,
|
frame->xwindow,
|
||||||
create_serial);
|
create_serial);
|
||||||
|
|
||||||
meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow);
|
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_display_register_x_window (window->display, &frame->xwindow, window);
|
||||||
|
|
||||||
@@ -128,28 +108,12 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
meta_stack_tracker_record_remove (window->screen->stack_tracker,
|
meta_stack_tracker_record_remove (window->screen->stack_tracker,
|
||||||
window->xwindow,
|
window->xwindow,
|
||||||
XNextRequest (window->display->xdisplay));
|
XNextRequest (window->display->xdisplay));
|
||||||
XReparentWindow (window->display->xdisplay,
|
|
||||||
window->xwindow,
|
|
||||||
frame->xwindow,
|
|
||||||
window->rect.x,
|
|
||||||
window->rect.y);
|
|
||||||
/* FIXME handle this error */
|
/* FIXME handle this error */
|
||||||
meta_error_trap_pop (window->display);
|
meta_error_trap_pop (window->display);
|
||||||
|
|
||||||
/* stick frame to the window */
|
/* stick frame to the window */
|
||||||
window->frame = frame;
|
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 */
|
/* Move keybindings to frame instead of window */
|
||||||
meta_window_grab_keys (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,
|
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
||||||
window->xwindow,
|
window->xwindow,
|
||||||
XNextRequest (window->display->xdisplay));
|
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_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,
|
meta_display_unregister_x_window (window->display,
|
||||||
frame->xwindow);
|
frame->xwindow);
|
||||||
@@ -309,22 +264,7 @@ void
|
|||||||
meta_frame_calc_borders (MetaFrame *frame,
|
meta_frame_calc_borders (MetaFrame *frame,
|
||||||
MetaFrameBorders *borders)
|
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);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -346,61 +286,32 @@ meta_frame_sync_to_window (MetaFrame *frame,
|
|||||||
frame->rect.x + frame->rect.width,
|
frame->rect.x + frame->rect.width,
|
||||||
frame->rect.y + frame->rect.height);
|
frame->rect.y + frame->rect.height);
|
||||||
|
|
||||||
/* set bg to none to avoid flicker */
|
XMoveResizeWindow (frame->window->display->xdisplay,
|
||||||
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->xwindow,
|
||||||
frame->rect.x,
|
frame->rect.x,
|
||||||
frame->rect.y,
|
frame->rect.y,
|
||||||
frame->rect.width,
|
frame->rect.width,
|
||||||
frame->rect.height);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return need_resize;
|
return need_resize;
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_region_t *
|
cairo_region_t *
|
||||||
meta_frame_get_frame_bounds (MetaFrame *frame)
|
meta_frame_get_frame_bounds (MetaFrame *frame)
|
||||||
{
|
{
|
||||||
return meta_ui_get_frame_bounds (frame->window->screen->ui,
|
cairo_rectangle_int_t rect;
|
||||||
frame->xwindow,
|
|
||||||
frame->rect.width,
|
|
||||||
frame->rect.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
rect.x = frame->window->rect.x;
|
||||||
meta_frame_get_mask (MetaFrame *frame,
|
rect.y = frame->window->rect.y;
|
||||||
cairo_t *cr)
|
rect.width = frame->window->rect.width;
|
||||||
{
|
rect.height = frame->window->rect.height;
|
||||||
meta_ui_get_frame_mask (frame->window->screen->ui, frame->xwindow,
|
|
||||||
frame->rect.width, frame->rect.height, cr);
|
return cairo_region_create_rectangles (&rect, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_frame_queue_draw (MetaFrame *frame)
|
meta_frame_queue_draw (MetaFrame *frame)
|
||||||
{
|
{
|
||||||
meta_ui_queue_frame_draw (frame->window->screen->ui,
|
|
||||||
frame->xwindow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -72,9 +72,6 @@ void meta_frame_clear_cached_borders (MetaFrame *frame);
|
|||||||
|
|
||||||
cairo_region_t *meta_frame_get_frame_bounds (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,
|
void meta_frame_set_screen_cursor (MetaFrame *frame,
|
||||||
MetaCursor cursor);
|
MetaCursor cursor);
|
||||||
|
|
||||||
|
@@ -134,16 +134,6 @@ static gboolean process_keyboard_resize_grab (MetaDisplay *display,
|
|||||||
XIDeviceEvent *event,
|
XIDeviceEvent *event,
|
||||||
KeySym keysym);
|
KeySym keysym);
|
||||||
|
|
||||||
static gboolean process_tab_grab (MetaDisplay *display,
|
|
||||||
MetaScreen *screen,
|
|
||||||
XIDeviceEvent *event,
|
|
||||||
KeySym keysym);
|
|
||||||
|
|
||||||
static gboolean process_workspace_switch_grab (MetaDisplay *display,
|
|
||||||
MetaScreen *screen,
|
|
||||||
XIDeviceEvent *event,
|
|
||||||
KeySym keysym);
|
|
||||||
|
|
||||||
static void grab_key_bindings (MetaDisplay *display);
|
static void grab_key_bindings (MetaDisplay *display);
|
||||||
static void ungrab_key_bindings (MetaDisplay *display);
|
static void ungrab_key_bindings (MetaDisplay *display);
|
||||||
|
|
||||||
@@ -1672,48 +1662,6 @@ is_modifier (MetaDisplay *display,
|
|||||||
* mod5 = 7
|
* mod5 = 7
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static gboolean
|
|
||||||
is_specific_modifier (MetaDisplay *display,
|
|
||||||
unsigned int keycode,
|
|
||||||
unsigned int mask)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int end;
|
|
||||||
gboolean retval = FALSE;
|
|
||||||
int mod_index;
|
|
||||||
|
|
||||||
g_assert (display->modmap);
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Checking whether code 0x%x is bound to modifier 0x%x\n",
|
|
||||||
keycode, mask);
|
|
||||||
|
|
||||||
mod_index = 0;
|
|
||||||
mask = mask >> 1;
|
|
||||||
while (mask != 0)
|
|
||||||
{
|
|
||||||
mod_index += 1;
|
|
||||||
mask = mask >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Modifier has index %d\n", mod_index);
|
|
||||||
|
|
||||||
end = (mod_index + 1) * display->modmap->max_keypermod;
|
|
||||||
i = mod_index * display->modmap->max_keypermod;
|
|
||||||
while (i < end)
|
|
||||||
{
|
|
||||||
if (keycode == display->modmap->modifiermap[i])
|
|
||||||
{
|
|
||||||
retval = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
get_primary_modifier (MetaDisplay *display,
|
get_primary_modifier (MetaDisplay *display,
|
||||||
unsigned int entire_binding_mask)
|
unsigned int entire_binding_mask)
|
||||||
@@ -1741,24 +1689,6 @@ get_primary_modifier (MetaDisplay *display,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
keycode_is_primary_modifier (MetaDisplay *display,
|
|
||||||
unsigned int keycode,
|
|
||||||
unsigned int entire_binding_mask)
|
|
||||||
{
|
|
||||||
unsigned int primary_modifier;
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Checking whether code 0x%x is the primary modifier of mask 0x%x\n",
|
|
||||||
keycode, entire_binding_mask);
|
|
||||||
|
|
||||||
primary_modifier = get_primary_modifier (display, entire_binding_mask);
|
|
||||||
if (primary_modifier != 0)
|
|
||||||
return is_specific_modifier (display, keycode, primary_modifier);
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
primary_modifier_still_pressed (MetaDisplay *display,
|
primary_modifier_still_pressed (MetaDisplay *display,
|
||||||
unsigned int entire_binding_mask)
|
unsigned int entire_binding_mask)
|
||||||
@@ -1820,20 +1750,6 @@ invoke_handler (MetaDisplay *display,
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
invoke_handler_by_name (MetaDisplay *display,
|
|
||||||
MetaScreen *screen,
|
|
||||||
const char *handler_name,
|
|
||||||
MetaWindow *window,
|
|
||||||
XIDeviceEvent *event)
|
|
||||||
{
|
|
||||||
MetaKeyHandler *handler;
|
|
||||||
|
|
||||||
handler = HANDLER (handler_name);
|
|
||||||
if (handler)
|
|
||||||
invoke_handler (display, screen, handler, window, event, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
process_event (MetaKeyBinding *bindings,
|
process_event (MetaKeyBinding *bindings,
|
||||||
int n_bindings,
|
int n_bindings,
|
||||||
@@ -2067,10 +1983,6 @@ meta_display_process_key_event (MetaDisplay *display,
|
|||||||
if (screen == NULL)
|
if (screen == NULL)
|
||||||
return FALSE; /* event window is destroyed */
|
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 */
|
/* window may be NULL */
|
||||||
|
|
||||||
keysym = XKeycodeToKeysym (display->xdisplay, event->detail, 0);
|
keysym = XKeycodeToKeysym (display->xdisplay, event->detail, 0);
|
||||||
@@ -2153,23 +2065,6 @@ meta_display_process_key_event (MetaDisplay *display,
|
|||||||
window, event, keysym);
|
window, event, keysym);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
|
|
||||||
case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
|
|
||||||
case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
|
|
||||||
case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
|
|
||||||
case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
|
|
||||||
case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Processing event for keyboard tabbing/cycling\n");
|
|
||||||
keep_grab = process_tab_grab (display, screen, event, keysym);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING:
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Processing event for keyboard workspace switching\n");
|
|
||||||
keep_grab = process_workspace_switch_grab (display, screen, event, keysym);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2719,348 +2614,6 @@ process_keyboard_resize_grab (MetaDisplay *display,
|
|||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
end_keyboard_grab (MetaDisplay *display,
|
|
||||||
unsigned int keycode)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_XKB
|
|
||||||
if (display->xkb_base_event_type > 0)
|
|
||||||
{
|
|
||||||
unsigned int primary_modifier;
|
|
||||||
XkbStateRec state;
|
|
||||||
|
|
||||||
primary_modifier = get_primary_modifier (display, display->grab_mask);
|
|
||||||
|
|
||||||
XkbGetState (display->xdisplay, XkbUseCoreKbd, &state);
|
|
||||||
|
|
||||||
if (!(primary_modifier & state.mods))
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
if (keycode_is_primary_modifier (display, keycode, display->grab_mask))
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
process_tab_grab (MetaDisplay *display,
|
|
||||||
MetaScreen *screen,
|
|
||||||
XIDeviceEvent *event,
|
|
||||||
KeySym keysym)
|
|
||||||
{
|
|
||||||
MetaKeyBinding *binding;
|
|
||||||
MetaKeyBindingAction action;
|
|
||||||
gboolean popup_not_showing;
|
|
||||||
gboolean backward;
|
|
||||||
gboolean key_used;
|
|
||||||
MetaWindow *prev_window;
|
|
||||||
|
|
||||||
if (screen != display->grab_screen)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
binding = display_get_keybinding (display,
|
|
||||||
keysym,
|
|
||||||
event->detail,
|
|
||||||
display->grab_mask);
|
|
||||||
if (binding)
|
|
||||||
action = meta_prefs_get_keybinding_action (binding->name);
|
|
||||||
else
|
|
||||||
action = META_KEYBINDING_ACTION_NONE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If there is no tab_pop up object, i.e., there is some custom handler
|
|
||||||
* implementing Alt+Tab & Co., we call this custom handler; we do not
|
|
||||||
* mess about with the grab, as that is up to the handler to deal with.
|
|
||||||
*/
|
|
||||||
if (!screen->tab_popup)
|
|
||||||
{
|
|
||||||
if (event->evtype == XI_KeyRelease)
|
|
||||||
{
|
|
||||||
if (end_keyboard_grab (display, event->detail))
|
|
||||||
{
|
|
||||||
invoke_handler_by_name (display, screen, "tab-popup-select", NULL, event);
|
|
||||||
|
|
||||||
/* We return FALSE to end the grab; if the handler ended the grab itself
|
|
||||||
* that will be a noop. If the handler didn't end the grab, then it's a
|
|
||||||
* safety measure to prevent a stuck grab.
|
|
||||||
*/
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (action)
|
|
||||||
{
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_PANELS:
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_WINDOWS:
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_PANELS:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_GROUP:
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_GROUP:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
|
|
||||||
/* These are the tab-popup bindings. If a custom Alt-Tab implementation
|
|
||||||
* is in effect, we expect it to want to handle all of these as a group
|
|
||||||
*
|
|
||||||
* If there are some of them that the custom implementation didn't
|
|
||||||
* handle, we treat them as "unbound" for the duration - running the
|
|
||||||
* normal handlers could get us into trouble.
|
|
||||||
*/
|
|
||||||
if (binding->handler &&
|
|
||||||
binding->handler->func &&
|
|
||||||
binding->handler->func != binding->handler->default_func)
|
|
||||||
{
|
|
||||||
invoke_handler (display, screen, binding->handler, NULL, event, binding);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case META_KEYBINDING_ACTION_NONE:
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If this is simply user pressing the Shift key, we do not want
|
|
||||||
* to cancel the grab.
|
|
||||||
*/
|
|
||||||
if (is_modifier (display, event->detail))
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some unhandled key press */
|
|
||||||
invoke_handler_by_name (display, screen, "tab-popup-cancel", NULL, event);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event->evtype == XI_KeyRelease &&
|
|
||||||
end_keyboard_grab (display, event->detail))
|
|
||||||
{
|
|
||||||
/* We're done, move to the new window. */
|
|
||||||
MetaWindow *target_window;
|
|
||||||
|
|
||||||
target_window = meta_screen_tab_popup_get_selected (screen);
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Ending tab operation, primary modifier released\n");
|
|
||||||
|
|
||||||
if (target_window)
|
|
||||||
{
|
|
||||||
target_window->tab_unminimized = FALSE;
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Activating target window\n");
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_FOCUS, "Activating %s due to tab popup "
|
|
||||||
"selection and turning mouse_mode off\n",
|
|
||||||
target_window->desc);
|
|
||||||
display->mouse_mode = FALSE;
|
|
||||||
meta_window_activate (target_window, event->time);
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Ending grab early so we can focus the target window\n");
|
|
||||||
meta_display_end_grab_op (display, event->time);
|
|
||||||
|
|
||||||
return TRUE; /* we already ended the grab */
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE; /* end grab */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* don't care about other releases, but eat them, don't end grab */
|
|
||||||
if (event->evtype == XI_KeyRelease)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* don't end grab on modifier key presses */
|
|
||||||
if (is_modifier (display, event->detail))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
prev_window = meta_screen_tab_popup_get_selected (screen);
|
|
||||||
|
|
||||||
/* Cancel when alt-Escape is pressed during using alt-Tab, and vice
|
|
||||||
* versa.
|
|
||||||
*/
|
|
||||||
switch (action)
|
|
||||||
{
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_PANELS:
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_WINDOWS:
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD:
|
|
||||||
/* CYCLE_* are traditionally Escape-based actions,
|
|
||||||
* and should cancel traditionally Tab-based ones.
|
|
||||||
*/
|
|
||||||
switch (display->grab_op)
|
|
||||||
{
|
|
||||||
case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
|
|
||||||
case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
|
|
||||||
/* carry on */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_PANELS:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD:
|
|
||||||
/* SWITCH_* are traditionally Tab-based actions,
|
|
||||||
* and should cancel traditionally Escape-based ones.
|
|
||||||
*/
|
|
||||||
switch (display->grab_op)
|
|
||||||
{
|
|
||||||
case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
|
|
||||||
case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
|
|
||||||
/* carry on */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Also, we must re-lower and re-minimize whatever window
|
|
||||||
* we'd previously raised and unminimized.
|
|
||||||
*/
|
|
||||||
meta_stack_set_positions (screen->stack,
|
|
||||||
screen->display->grab_old_window_stacking);
|
|
||||||
if (prev_window && prev_window->tab_unminimized)
|
|
||||||
{
|
|
||||||
meta_window_minimize (prev_window);
|
|
||||||
prev_window->tab_unminimized = FALSE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_GROUP:
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_GROUP:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
|
|
||||||
switch (display->grab_op)
|
|
||||||
{
|
|
||||||
case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
|
|
||||||
case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
|
|
||||||
/* carry on */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* !! TO HERE !!
|
|
||||||
* alt-f6 during alt-{Tab,Escape} does not end the grab
|
|
||||||
* but does change the grab op (and redraws the window,
|
|
||||||
* of course).
|
|
||||||
* See _{SWITCH,CYCLE}_GROUP.@@@
|
|
||||||
*/
|
|
||||||
|
|
||||||
popup_not_showing = FALSE;
|
|
||||||
key_used = FALSE;
|
|
||||||
backward = FALSE;
|
|
||||||
|
|
||||||
switch (action)
|
|
||||||
{
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_PANELS:
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_WINDOWS:
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_GROUP:
|
|
||||||
popup_not_showing = TRUE;
|
|
||||||
key_used = TRUE;
|
|
||||||
break;
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
|
|
||||||
popup_not_showing = TRUE;
|
|
||||||
key_used = TRUE;
|
|
||||||
backward = TRUE;
|
|
||||||
break;
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_PANELS:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_GROUP:
|
|
||||||
key_used = TRUE;
|
|
||||||
break;
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD:
|
|
||||||
case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
|
|
||||||
key_used = TRUE;
|
|
||||||
backward = TRUE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key_used)
|
|
||||||
{
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Key pressed, moving tab focus in popup\n");
|
|
||||||
|
|
||||||
if (event->mods.effective & ShiftMask)
|
|
||||||
backward = !backward;
|
|
||||||
|
|
||||||
if (backward)
|
|
||||||
meta_screen_tab_popup_backward (screen);
|
|
||||||
else
|
|
||||||
meta_screen_tab_popup_forward (screen);
|
|
||||||
|
|
||||||
if (popup_not_showing)
|
|
||||||
{
|
|
||||||
/* We can't actually change window focus, due to the grab.
|
|
||||||
* but raise the window.
|
|
||||||
*/
|
|
||||||
MetaWindow *target_window;
|
|
||||||
|
|
||||||
meta_stack_set_positions (screen->stack,
|
|
||||||
display->grab_old_window_stacking);
|
|
||||||
|
|
||||||
target_window = meta_screen_tab_popup_get_selected (screen);
|
|
||||||
|
|
||||||
if (prev_window && prev_window->tab_unminimized)
|
|
||||||
{
|
|
||||||
prev_window->tab_unminimized = FALSE;
|
|
||||||
meta_window_minimize (prev_window);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target_window)
|
|
||||||
{
|
|
||||||
meta_window_raise (target_window);
|
|
||||||
target_window->tab_unminimized = target_window->minimized;
|
|
||||||
meta_window_unminimize (target_window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* end grab */
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Ending tabbing/cycling, uninteresting key pressed\n");
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Syncing to old stack positions.\n");
|
|
||||||
meta_stack_set_positions (screen->stack,
|
|
||||||
screen->display->grab_old_window_stacking);
|
|
||||||
|
|
||||||
if (prev_window && prev_window->tab_unminimized)
|
|
||||||
{
|
|
||||||
meta_window_minimize (prev_window);
|
|
||||||
prev_window->tab_unminimized = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return key_used;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_switch_to_workspace (MetaDisplay *display,
|
handle_switch_to_workspace (MetaDisplay *display,
|
||||||
MetaScreen *screen,
|
MetaScreen *screen,
|
||||||
@@ -3313,120 +2866,6 @@ handle_move_to_center (MetaDisplay *display,
|
|||||||
window->rect.height);
|
window->rect.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
process_workspace_switch_grab (MetaDisplay *display,
|
|
||||||
MetaScreen *screen,
|
|
||||||
XIDeviceEvent *event,
|
|
||||||
KeySym keysym)
|
|
||||||
{
|
|
||||||
MetaWorkspace *workspace;
|
|
||||||
|
|
||||||
if (screen != display->grab_screen || !screen->ws_popup)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (event->evtype == XI_KeyRelease &&
|
|
||||||
end_keyboard_grab (display, event->detail))
|
|
||||||
{
|
|
||||||
/* We're done, move to the new workspace. */
|
|
||||||
MetaWorkspace *target_workspace;
|
|
||||||
|
|
||||||
target_workspace = meta_screen_workspace_popup_get_selected (screen);
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Ending workspace tab operation, primary modifier released\n");
|
|
||||||
|
|
||||||
if (target_workspace == screen->active_workspace)
|
|
||||||
{
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Ending grab so we can focus on the target workspace\n");
|
|
||||||
meta_display_end_grab_op (display, event->time);
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Focusing default window on target workspace\n");
|
|
||||||
|
|
||||||
meta_workspace_focus_default_window (target_workspace,
|
|
||||||
NULL,
|
|
||||||
event->time);
|
|
||||||
|
|
||||||
return TRUE; /* we already ended the grab */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Workspace switching should have already occurred on KeyPress */
|
|
||||||
meta_warning ("target_workspace != active_workspace. Some other event must have occurred.\n");
|
|
||||||
|
|
||||||
return FALSE; /* end grab */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* don't care about other releases, but eat them, don't end grab */
|
|
||||||
if (event->evtype == XI_KeyRelease)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* don't end grab on modifier key presses */
|
|
||||||
if (is_modifier (display, event->detail))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* select the next workspace in the popup */
|
|
||||||
workspace = meta_screen_workspace_popup_get_selected (screen);
|
|
||||||
|
|
||||||
if (workspace)
|
|
||||||
{
|
|
||||||
MetaWorkspace *target_workspace;
|
|
||||||
MetaKeyBindingAction action;
|
|
||||||
|
|
||||||
action = meta_display_get_keybinding_action (display,
|
|
||||||
event->detail,
|
|
||||||
display->grab_mask);
|
|
||||||
|
|
||||||
switch (action)
|
|
||||||
{
|
|
||||||
case META_KEYBINDING_ACTION_WORKSPACE_UP:
|
|
||||||
target_workspace = meta_workspace_get_neighbor (workspace,
|
|
||||||
META_MOTION_UP);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case META_KEYBINDING_ACTION_WORKSPACE_DOWN:
|
|
||||||
target_workspace = meta_workspace_get_neighbor (workspace,
|
|
||||||
META_MOTION_DOWN);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case META_KEYBINDING_ACTION_WORKSPACE_LEFT:
|
|
||||||
target_workspace = meta_workspace_get_neighbor (workspace,
|
|
||||||
META_MOTION_LEFT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case META_KEYBINDING_ACTION_WORKSPACE_RIGHT:
|
|
||||||
target_workspace = meta_workspace_get_neighbor (workspace,
|
|
||||||
META_MOTION_RIGHT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
target_workspace = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target_workspace)
|
|
||||||
{
|
|
||||||
meta_screen_workspace_popup_select (screen, target_workspace);
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Tab key pressed, moving tab focus in popup\n");
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Activating target workspace\n");
|
|
||||||
|
|
||||||
meta_workspace_activate (target_workspace, event->time);
|
|
||||||
|
|
||||||
return TRUE; /* we already ended the grab */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end grab */
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Ending workspace tabbing & focusing default window; uninteresting key pressed\n");
|
|
||||||
workspace = meta_screen_workspace_popup_get_selected (screen);
|
|
||||||
meta_workspace_focus_default_window (workspace, NULL, event->time);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_show_desktop (MetaDisplay *display,
|
handle_show_desktop (MetaDisplay *display,
|
||||||
MetaScreen *screen,
|
MetaScreen *screen,
|
||||||
@@ -3523,60 +2962,19 @@ handle_activate_window_menu (MetaDisplay *display,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaGrabOp
|
|
||||||
tab_op_from_tab_type (MetaTabList type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case META_TAB_LIST_NORMAL:
|
|
||||||
return META_GRAB_OP_KEYBOARD_TABBING_NORMAL;
|
|
||||||
case META_TAB_LIST_DOCKS:
|
|
||||||
return META_GRAB_OP_KEYBOARD_TABBING_DOCK;
|
|
||||||
case META_TAB_LIST_GROUP:
|
|
||||||
return META_GRAB_OP_KEYBOARD_TABBING_GROUP;
|
|
||||||
case META_TAB_LIST_NORMAL_ALL:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_assert_not_reached ();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static MetaGrabOp
|
|
||||||
cycle_op_from_tab_type (MetaTabList type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case META_TAB_LIST_NORMAL:
|
|
||||||
return META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL;
|
|
||||||
case META_TAB_LIST_DOCKS:
|
|
||||||
return META_GRAB_OP_KEYBOARD_ESCAPING_DOCK;
|
|
||||||
case META_TAB_LIST_GROUP:
|
|
||||||
return META_GRAB_OP_KEYBOARD_ESCAPING_GROUP;
|
|
||||||
case META_TAB_LIST_NORMAL_ALL:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_assert_not_reached ();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_choose_window (MetaDisplay *display,
|
do_choose_window (MetaDisplay *display,
|
||||||
MetaScreen *screen,
|
MetaScreen *screen,
|
||||||
MetaWindow *event_window,
|
MetaWindow *event_window,
|
||||||
XIDeviceEvent *event,
|
XIDeviceEvent *event,
|
||||||
MetaKeyBinding *binding,
|
MetaKeyBinding *binding,
|
||||||
gboolean backward,
|
gboolean backward)
|
||||||
gboolean show_popup)
|
|
||||||
{
|
{
|
||||||
MetaTabList type = binding->handler->data;
|
MetaTabList type = binding->handler->data;
|
||||||
MetaWindow *initial_selection;
|
MetaWindow *initial_selection;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||||
"Tab list = %u show_popup = %d\n", type, show_popup);
|
"Tab list = %u\n", type);
|
||||||
|
|
||||||
/* reverse direction if shift is down */
|
/* reverse direction if shift is down */
|
||||||
if (event->mods.effective & ShiftMask)
|
if (event->mods.effective & ShiftMask)
|
||||||
@@ -3589,82 +2987,7 @@ do_choose_window (MetaDisplay *display,
|
|||||||
NULL,
|
NULL,
|
||||||
backward);
|
backward);
|
||||||
|
|
||||||
/* Note that focus_window may not be in the tab chain, but it's OK */
|
|
||||||
if (initial_selection == NULL)
|
|
||||||
initial_selection = meta_display_get_tab_current (display,
|
|
||||||
type, screen,
|
|
||||||
screen->active_workspace);
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Initially selecting window %s\n",
|
|
||||||
initial_selection ? initial_selection->desc : "(none)");
|
|
||||||
|
|
||||||
if (initial_selection == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (binding->mask == 0)
|
|
||||||
{
|
|
||||||
/* If no modifiers, we can't do the "hold down modifier to keep
|
|
||||||
* moving" thing, so we just instaswitch by one window.
|
|
||||||
*/
|
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
|
||||||
"Activating %s and turning off mouse_mode due to "
|
|
||||||
"switch/cycle windows with no modifiers\n",
|
|
||||||
initial_selection->desc);
|
|
||||||
display->mouse_mode = FALSE;
|
|
||||||
meta_window_activate (initial_selection, event->time);
|
meta_window_activate (initial_selection, event->time);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meta_prefs_get_no_tab_popup ())
|
|
||||||
{
|
|
||||||
/* FIXME? Shouldn't this be merged with the previous case? */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!meta_display_begin_grab_op (display,
|
|
||||||
screen,
|
|
||||||
NULL,
|
|
||||||
show_popup ?
|
|
||||||
tab_op_from_tab_type (type) :
|
|
||||||
cycle_op_from_tab_type (type),
|
|
||||||
FALSE,
|
|
||||||
FALSE,
|
|
||||||
0,
|
|
||||||
binding->mask,
|
|
||||||
event->time,
|
|
||||||
0, 0))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!primary_modifier_still_pressed (display, binding->mask))
|
|
||||||
{
|
|
||||||
/* This handles a race where modifier might be released before
|
|
||||||
* we establish the grab. must end grab prior to trying to focus
|
|
||||||
* a window.
|
|
||||||
*/
|
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
|
||||||
"Ending grab, activating %s, and turning off "
|
|
||||||
"mouse_mode due to switch/cycle windows where "
|
|
||||||
"modifier was released prior to grab\n",
|
|
||||||
initial_selection->desc);
|
|
||||||
meta_display_end_grab_op (display, event->time);
|
|
||||||
display->mouse_mode = FALSE;
|
|
||||||
meta_window_activate (initial_selection, event->time);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_screen_tab_popup_create (screen, type,
|
|
||||||
show_popup ? META_TAB_SHOW_ICON :
|
|
||||||
META_TAB_SHOW_INSTANTLY,
|
|
||||||
initial_selection);
|
|
||||||
|
|
||||||
if (!show_popup)
|
|
||||||
{
|
|
||||||
meta_window_raise (initial_selection);
|
|
||||||
initial_selection->tab_unminimized =
|
|
||||||
initial_selection->minimized;
|
|
||||||
meta_window_unminimize (initial_selection);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -3677,8 +3000,7 @@ handle_switch (MetaDisplay *display,
|
|||||||
{
|
{
|
||||||
gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
|
gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
|
||||||
|
|
||||||
do_choose_window (display, screen, event_window, event, binding,
|
do_choose_window (display, screen, event_window, event, binding, backwards);
|
||||||
backwards, TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -3691,30 +3013,7 @@ handle_cycle (MetaDisplay *display,
|
|||||||
{
|
{
|
||||||
gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
|
gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
|
||||||
|
|
||||||
do_choose_window (display, screen, event_window, event, binding,
|
do_choose_window (display, screen, event_window, event, binding, backwards);
|
||||||
backwards, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
handle_tab_popup_select (MetaDisplay *display,
|
|
||||||
MetaScreen *screen,
|
|
||||||
MetaWindow *window,
|
|
||||||
XIDeviceEvent *event,
|
|
||||||
MetaKeyBinding *binding,
|
|
||||||
gpointer dummy)
|
|
||||||
{
|
|
||||||
/* Stub for custom handlers; no default implementation */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
handle_tab_popup_cancel (MetaDisplay *display,
|
|
||||||
MetaScreen *screen,
|
|
||||||
MetaWindow *window,
|
|
||||||
XIDeviceEvent *event,
|
|
||||||
MetaKeyBinding *binding,
|
|
||||||
gpointer dummy)
|
|
||||||
{
|
|
||||||
/* Stub for custom handlers; no default implementation */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -4112,9 +3411,6 @@ handle_workspace_switch (MetaDisplay *display,
|
|||||||
}
|
}
|
||||||
|
|
||||||
meta_workspace_activate (next, event->time);
|
meta_workspace_activate (next, event->time);
|
||||||
|
|
||||||
if (grabbed_before_release && !meta_prefs_get_no_tab_popup ())
|
|
||||||
meta_screen_workspace_popup_create (screen, next);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -4380,26 +3676,6 @@ init_builtin_key_bindings (MetaDisplay *display)
|
|||||||
META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD,
|
META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD,
|
||||||
handle_cycle, META_TAB_LIST_DOCKS);
|
handle_cycle, META_TAB_LIST_DOCKS);
|
||||||
|
|
||||||
|
|
||||||
/* These two are special pseudo-bindings that are provided for allowing
|
|
||||||
* custom handlers, but will never be bound to a key. While a tab
|
|
||||||
* grab is in effect, they are invoked for releasing the primary modifier
|
|
||||||
* or pressing some unbound key, respectively.
|
|
||||||
*/
|
|
||||||
add_builtin_keybinding (display,
|
|
||||||
"tab-popup-select",
|
|
||||||
mutter_keybindings,
|
|
||||||
META_KEY_BINDING_NONE,
|
|
||||||
META_KEYBINDING_ACTION_TAB_POPUP_SELECT,
|
|
||||||
handle_tab_popup_select, 0);
|
|
||||||
|
|
||||||
add_builtin_keybinding (display,
|
|
||||||
"tab-popup-cancel",
|
|
||||||
mutter_keybindings,
|
|
||||||
META_KEY_BINDING_NONE,
|
|
||||||
META_KEYBINDING_ACTION_TAB_POPUP_CANCEL,
|
|
||||||
handle_tab_popup_cancel, 0);
|
|
||||||
|
|
||||||
/***********************************/
|
/***********************************/
|
||||||
|
|
||||||
add_builtin_keybinding (display,
|
add_builtin_keybinding (display,
|
||||||
|
@@ -524,42 +524,6 @@ meta_run (void)
|
|||||||
if (g_getenv ("MUTTER_G_FATAL_WARNINGS") != NULL)
|
if (g_getenv ("MUTTER_G_FATAL_WARNINGS") != NULL)
|
||||||
g_log_set_always_fatal (G_LOG_LEVEL_MASK);
|
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 ())
|
if (!meta_display_open ())
|
||||||
meta_exit (META_EXIT_ERROR);
|
meta_exit (META_EXIT_ERROR);
|
||||||
|
|
||||||
@@ -606,12 +570,6 @@ prefs_changed_callback (MetaPreference pref,
|
|||||||
{
|
{
|
||||||
switch (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_THEME:
|
||||||
case META_PREF_CURSOR_SIZE:
|
case META_PREF_CURSOR_SIZE:
|
||||||
meta_display_set_cursor_theme (meta_prefs_get_cursor_theme (),
|
meta_display_set_cursor_theme (meta_prefs_get_cursor_theme (),
|
||||||
|
@@ -57,7 +57,6 @@
|
|||||||
|
|
||||||
#define KEY_OVERLAY_KEY "overlay-key"
|
#define KEY_OVERLAY_KEY "overlay-key"
|
||||||
#define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary"
|
#define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary"
|
||||||
#define KEY_NO_TAB_POPUP "no-tab-popup"
|
|
||||||
|
|
||||||
/* These are the different schemas we are keeping
|
/* These are the different schemas we are keeping
|
||||||
* a GSettings instance for */
|
* a GSettings instance for */
|
||||||
@@ -81,7 +80,6 @@ static GDesktopFocusMode focus_mode = G_DESKTOP_FOCUS_MODE_CLICK;
|
|||||||
static GDesktopFocusNewWindows focus_new_windows = G_DESKTOP_FOCUS_NEW_WINDOWS_SMART;
|
static GDesktopFocusNewWindows focus_new_windows = G_DESKTOP_FOCUS_NEW_WINDOWS_SMART;
|
||||||
static gboolean raise_on_click = TRUE;
|
static gboolean raise_on_click = TRUE;
|
||||||
static gboolean attach_modal_dialogs = FALSE;
|
static gboolean attach_modal_dialogs = FALSE;
|
||||||
static char* current_theme = NULL;
|
|
||||||
static int num_workspaces = 4;
|
static int num_workspaces = 4;
|
||||||
static GDesktopTitlebarAction action_double_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE;
|
static GDesktopTitlebarAction action_double_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE;
|
||||||
static GDesktopTitlebarAction action_middle_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_LOWER;
|
static GDesktopTitlebarAction action_middle_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_LOWER;
|
||||||
@@ -112,8 +110,6 @@ static char **workspace_names = NULL;
|
|||||||
|
|
||||||
static gboolean workspaces_only_on_primary = FALSE;
|
static gboolean workspaces_only_on_primary = FALSE;
|
||||||
|
|
||||||
static gboolean no_tab_popup = FALSE;
|
|
||||||
|
|
||||||
static char *iso_next_group_option = NULL;
|
static char *iso_next_group_option = NULL;
|
||||||
|
|
||||||
static void handle_preference_update_enum (GSettings *settings,
|
static void handle_preference_update_enum (GSettings *settings,
|
||||||
@@ -135,7 +131,6 @@ static void queue_changed (MetaPreference pref);
|
|||||||
static void maybe_give_disable_workarounds_warning (void);
|
static void maybe_give_disable_workarounds_warning (void);
|
||||||
|
|
||||||
static gboolean titlebar_handler (GVariant*, gpointer*, gpointer);
|
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 mouse_button_mods_handler (GVariant*, gpointer*, gpointer);
|
||||||
static gboolean button_layout_handler (GVariant*, gpointer*, gpointer);
|
static gboolean button_layout_handler (GVariant*, gpointer*, gpointer);
|
||||||
static gboolean overlay_key_handler (GVariant*, gpointer*, gpointer);
|
static gboolean overlay_key_handler (GVariant*, gpointer*, gpointer);
|
||||||
@@ -365,13 +360,6 @@ static MetaBoolPreference preferences_bool[] =
|
|||||||
},
|
},
|
||||||
&workspaces_only_on_primary,
|
&workspaces_only_on_primary,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
{ KEY_NO_TAB_POPUP,
|
|
||||||
SCHEMA_MUTTER,
|
|
||||||
META_PREF_NO_TAB_POPUP,
|
|
||||||
},
|
|
||||||
&no_tab_popup,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
{ "auto-maximize",
|
{ "auto-maximize",
|
||||||
SCHEMA_MUTTER,
|
SCHEMA_MUTTER,
|
||||||
@@ -392,14 +380,6 @@ static MetaStringPreference preferences_string[] =
|
|||||||
mouse_button_mods_handler,
|
mouse_button_mods_handler,
|
||||||
NULL,
|
NULL,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
{ "theme",
|
|
||||||
SCHEMA_GENERAL,
|
|
||||||
META_PREF_THEME,
|
|
||||||
},
|
|
||||||
theme_name_handler,
|
|
||||||
NULL,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
{ KEY_TITLEBAR_FONT,
|
{ KEY_TITLEBAR_FONT,
|
||||||
SCHEMA_GENERAL,
|
SCHEMA_GENERAL,
|
||||||
@@ -1235,12 +1215,6 @@ meta_prefs_get_raise_on_click (void)
|
|||||||
return raise_on_click || focus_mode == G_DESKTOP_FOCUS_MODE_CLICK;
|
return raise_on_click || focus_mode == G_DESKTOP_FOCUS_MODE_CLICK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char*
|
|
||||||
meta_prefs_get_theme (void)
|
|
||||||
{
|
|
||||||
return current_theme;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
meta_prefs_get_cursor_theme (void)
|
meta_prefs_get_cursor_theme (void)
|
||||||
{
|
{
|
||||||
@@ -1297,31 +1271,6 @@ titlebar_handler (GVariant *value,
|
|||||||
return TRUE;
|
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
|
static gboolean
|
||||||
mouse_button_mods_handler (GVariant *value,
|
mouse_button_mods_handler (GVariant *value,
|
||||||
gpointer *result,
|
gpointer *result,
|
||||||
@@ -1741,9 +1690,6 @@ meta_preference_to_string (MetaPreference pref)
|
|||||||
case META_PREF_RAISE_ON_CLICK:
|
case META_PREF_RAISE_ON_CLICK:
|
||||||
return "RAISE_ON_CLICK";
|
return "RAISE_ON_CLICK";
|
||||||
|
|
||||||
case META_PREF_THEME:
|
|
||||||
return "THEME";
|
|
||||||
|
|
||||||
case META_PREF_TITLEBAR_FONT:
|
case META_PREF_TITLEBAR_FONT:
|
||||||
return "TITLEBAR_FONT";
|
return "TITLEBAR_FONT";
|
||||||
|
|
||||||
@@ -1813,9 +1759,6 @@ meta_preference_to_string (MetaPreference pref)
|
|||||||
case META_PREF_WORKSPACES_ONLY_ON_PRIMARY:
|
case META_PREF_WORKSPACES_ONLY_ON_PRIMARY:
|
||||||
return "WORKSPACES_ONLY_ON_PRIMARY";
|
return "WORKSPACES_ONLY_ON_PRIMARY";
|
||||||
|
|
||||||
case META_PREF_NO_TAB_POPUP:
|
|
||||||
return "NO_TAB_POPUP";
|
|
||||||
|
|
||||||
case META_PREF_DRAGGABLE_BORDER_WIDTH:
|
case META_PREF_DRAGGABLE_BORDER_WIDTH:
|
||||||
return "DRAGGABLE_BORDER_WIDTH";
|
return "DRAGGABLE_BORDER_WIDTH";
|
||||||
|
|
||||||
@@ -2320,25 +2263,6 @@ meta_prefs_get_workspaces_only_on_primary (void)
|
|||||||
return workspaces_only_on_primary;
|
return workspaces_only_on_primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
meta_prefs_get_no_tab_popup (void)
|
|
||||||
{
|
|
||||||
return no_tab_popup;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_prefs_set_no_tab_popup (gboolean whether)
|
|
||||||
{
|
|
||||||
MetaBasePreference *pref;
|
|
||||||
|
|
||||||
if (find_pref (preferences_bool, sizeof(MetaBoolPreference),
|
|
||||||
KEY_NO_TAB_POPUP, &pref))
|
|
||||||
{
|
|
||||||
g_settings_set_boolean (SETTINGS (pref->schema), KEY_NO_TAB_POPUP, whether);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
meta_prefs_get_draggable_border_width (void)
|
meta_prefs_get_draggable_border_width (void)
|
||||||
{
|
{
|
||||||
|
@@ -64,7 +64,6 @@ struct _MetaScreen
|
|||||||
Visual *default_xvisual;
|
Visual *default_xvisual;
|
||||||
MetaRectangle rect; /* Size of screen; rect.x & rect.y are always 0 */
|
MetaRectangle rect; /* Size of screen; rect.x & rect.y are always 0 */
|
||||||
MetaUI *ui;
|
MetaUI *ui;
|
||||||
MetaTabPopup *tab_popup, *ws_popup;
|
|
||||||
|
|
||||||
guint tile_preview_timeout_id;
|
guint tile_preview_timeout_id;
|
||||||
|
|
||||||
@@ -150,26 +149,6 @@ void meta_screen_foreach_window (MetaScreen *scree
|
|||||||
|
|
||||||
void meta_screen_update_cursor (MetaScreen *screen);
|
void meta_screen_update_cursor (MetaScreen *screen);
|
||||||
|
|
||||||
void meta_screen_tab_popup_create (MetaScreen *screen,
|
|
||||||
MetaTabList list_type,
|
|
||||||
MetaTabShowType show_type,
|
|
||||||
MetaWindow *initial_window);
|
|
||||||
void meta_screen_tab_popup_forward (MetaScreen *screen);
|
|
||||||
void meta_screen_tab_popup_backward (MetaScreen *screen);
|
|
||||||
MetaWindow* meta_screen_tab_popup_get_selected (MetaScreen *screen);
|
|
||||||
void meta_screen_tab_popup_destroy (MetaScreen *screen);
|
|
||||||
|
|
||||||
void meta_screen_workspace_popup_create (MetaScreen *screen,
|
|
||||||
MetaWorkspace *initial_selection);
|
|
||||||
void meta_screen_workspace_popup_select (MetaScreen *screen,
|
|
||||||
MetaWorkspace *workspace);
|
|
||||||
MetaWorkspace*meta_screen_workspace_popup_get_selected (MetaScreen *screen);
|
|
||||||
void meta_screen_workspace_popup_destroy (MetaScreen *screen);
|
|
||||||
|
|
||||||
void meta_screen_update_tile_preview (MetaScreen *screen,
|
|
||||||
gboolean delay);
|
|
||||||
void meta_screen_hide_tile_preview (MetaScreen *screen);
|
|
||||||
|
|
||||||
MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen,
|
MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen,
|
||||||
MetaWindow *not_this_one);
|
MetaWindow *not_this_one);
|
||||||
|
|
||||||
|
@@ -760,9 +760,6 @@ meta_screen_new (MetaDisplay *display,
|
|||||||
screen->ui = meta_ui_new (screen->display->xdisplay,
|
screen->ui = meta_ui_new (screen->display->xdisplay,
|
||||||
screen->xscreen);
|
screen->xscreen);
|
||||||
|
|
||||||
screen->tab_popup = NULL;
|
|
||||||
screen->ws_popup = NULL;
|
|
||||||
|
|
||||||
screen->tile_preview_timeout_id = 0;
|
screen->tile_preview_timeout_id = 0;
|
||||||
|
|
||||||
screen->stack = meta_stack_new (screen);
|
screen->stack = meta_stack_new (screen);
|
||||||
@@ -1425,253 +1422,6 @@ meta_screen_update_cursor (MetaScreen *screen)
|
|||||||
screen->current_cursor);
|
screen->current_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
meta_screen_tab_popup_create (MetaScreen *screen,
|
|
||||||
MetaTabList list_type,
|
|
||||||
MetaTabShowType show_type,
|
|
||||||
MetaWindow *initial_selection)
|
|
||||||
{
|
|
||||||
MetaTabEntry *entries;
|
|
||||||
GList *tab_list;
|
|
||||||
GList *tmp;
|
|
||||||
int len;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (screen->tab_popup)
|
|
||||||
return;
|
|
||||||
|
|
||||||
tab_list = meta_display_get_tab_list (screen->display,
|
|
||||||
list_type,
|
|
||||||
screen,
|
|
||||||
screen->active_workspace);
|
|
||||||
|
|
||||||
len = g_list_length (tab_list);
|
|
||||||
|
|
||||||
entries = g_new (MetaTabEntry, len + 1);
|
|
||||||
entries[len].key = NULL;
|
|
||||||
entries[len].title = NULL;
|
|
||||||
entries[len].icon = NULL;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
tmp = tab_list;
|
|
||||||
while (i < len)
|
|
||||||
{
|
|
||||||
MetaWindow *window;
|
|
||||||
MetaRectangle r;
|
|
||||||
|
|
||||||
window = tmp->data;
|
|
||||||
|
|
||||||
entries[i].key = (MetaTabEntryKey) window;
|
|
||||||
entries[i].title = window->title;
|
|
||||||
entries[i].icon = g_object_ref (window->icon);
|
|
||||||
entries[i].blank = FALSE;
|
|
||||||
entries[i].hidden = !meta_window_showing_on_its_workspace (window);
|
|
||||||
entries[i].demands_attention = window->wm_state_demands_attention;
|
|
||||||
|
|
||||||
if (show_type == META_TAB_SHOW_INSTANTLY ||
|
|
||||||
!entries[i].hidden ||
|
|
||||||
!meta_window_get_icon_geometry (window, &r))
|
|
||||||
meta_window_get_frame_rect (window, &r);
|
|
||||||
|
|
||||||
entries[i].rect = r;
|
|
||||||
|
|
||||||
/* Find inside of highlight rectangle to be used when window is
|
|
||||||
* outlined for tabbing. This should be the size of the
|
|
||||||
* east/west frame, and the size of the south frame, on those
|
|
||||||
* sides. On the top it should be the size of the south frame
|
|
||||||
* edge.
|
|
||||||
*/
|
|
||||||
#define OUTLINE_WIDTH 5
|
|
||||||
/* Top side */
|
|
||||||
if (!entries[i].hidden &&
|
|
||||||
window->frame && window->frame->bottom_height > 0 &&
|
|
||||||
window->frame->child_y >= window->frame->bottom_height)
|
|
||||||
entries[i].inner_rect.y = window->frame->bottom_height;
|
|
||||||
else
|
|
||||||
entries[i].inner_rect.y = OUTLINE_WIDTH;
|
|
||||||
|
|
||||||
/* Bottom side */
|
|
||||||
if (!entries[i].hidden &&
|
|
||||||
window->frame && window->frame->bottom_height != 0)
|
|
||||||
entries[i].inner_rect.height = r.height
|
|
||||||
- entries[i].inner_rect.y - window->frame->bottom_height;
|
|
||||||
else
|
|
||||||
entries[i].inner_rect.height = r.height
|
|
||||||
- entries[i].inner_rect.y - OUTLINE_WIDTH;
|
|
||||||
|
|
||||||
/* Left side */
|
|
||||||
if (!entries[i].hidden && window->frame && window->frame->child_x != 0)
|
|
||||||
entries[i].inner_rect.x = window->frame->child_x;
|
|
||||||
else
|
|
||||||
entries[i].inner_rect.x = OUTLINE_WIDTH;
|
|
||||||
|
|
||||||
/* Right side */
|
|
||||||
if (!entries[i].hidden &&
|
|
||||||
window->frame && window->frame->right_width != 0)
|
|
||||||
entries[i].inner_rect.width = r.width
|
|
||||||
- entries[i].inner_rect.x - window->frame->right_width;
|
|
||||||
else
|
|
||||||
entries[i].inner_rect.width = r.width
|
|
||||||
- entries[i].inner_rect.x - OUTLINE_WIDTH;
|
|
||||||
|
|
||||||
++i;
|
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!meta_prefs_get_no_tab_popup ())
|
|
||||||
screen->tab_popup = meta_ui_tab_popup_new (entries,
|
|
||||||
screen->number,
|
|
||||||
len,
|
|
||||||
5, /* FIXME */
|
|
||||||
TRUE);
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
g_object_unref (entries[i].icon);
|
|
||||||
|
|
||||||
g_free (entries);
|
|
||||||
|
|
||||||
g_list_free (tab_list);
|
|
||||||
|
|
||||||
meta_ui_tab_popup_select (screen->tab_popup,
|
|
||||||
(MetaTabEntryKey) initial_selection);
|
|
||||||
|
|
||||||
if (show_type != META_TAB_SHOW_INSTANTLY)
|
|
||||||
meta_ui_tab_popup_set_showing (screen->tab_popup, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_screen_tab_popup_forward (MetaScreen *screen)
|
|
||||||
{
|
|
||||||
g_return_if_fail (screen->tab_popup != NULL);
|
|
||||||
|
|
||||||
meta_ui_tab_popup_forward (screen->tab_popup);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_screen_tab_popup_backward (MetaScreen *screen)
|
|
||||||
{
|
|
||||||
g_return_if_fail (screen->tab_popup != NULL);
|
|
||||||
|
|
||||||
meta_ui_tab_popup_backward (screen->tab_popup);
|
|
||||||
}
|
|
||||||
|
|
||||||
MetaWindow *
|
|
||||||
meta_screen_tab_popup_get_selected (MetaScreen *screen)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (screen->tab_popup != NULL, NULL);
|
|
||||||
|
|
||||||
return (MetaWindow *) meta_ui_tab_popup_get_selected (screen->tab_popup);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_screen_tab_popup_destroy (MetaScreen *screen)
|
|
||||||
{
|
|
||||||
if (screen->tab_popup)
|
|
||||||
{
|
|
||||||
meta_ui_tab_popup_free (screen->tab_popup);
|
|
||||||
screen->tab_popup = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_screen_workspace_popup_create (MetaScreen *screen,
|
|
||||||
MetaWorkspace *initial_selection)
|
|
||||||
{
|
|
||||||
MetaTabEntry *entries;
|
|
||||||
int len;
|
|
||||||
int i;
|
|
||||||
MetaWorkspaceLayout layout;
|
|
||||||
int n_workspaces;
|
|
||||||
int current_workspace;
|
|
||||||
|
|
||||||
if (screen->ws_popup || meta_prefs_get_no_tab_popup ())
|
|
||||||
return;
|
|
||||||
|
|
||||||
current_workspace = meta_workspace_index (screen->active_workspace);
|
|
||||||
n_workspaces = meta_screen_get_n_workspaces (screen);
|
|
||||||
|
|
||||||
meta_screen_calc_workspace_layout (screen, n_workspaces,
|
|
||||||
current_workspace, &layout);
|
|
||||||
|
|
||||||
len = layout.grid_area;
|
|
||||||
|
|
||||||
entries = g_new (MetaTabEntry, len + 1);
|
|
||||||
entries[len].key = NULL;
|
|
||||||
entries[len].title = NULL;
|
|
||||||
entries[len].icon = NULL;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (i < len)
|
|
||||||
{
|
|
||||||
if (layout.grid[i] >= 0)
|
|
||||||
{
|
|
||||||
MetaWorkspace *workspace;
|
|
||||||
|
|
||||||
workspace = meta_screen_get_workspace_by_index (screen,
|
|
||||||
layout.grid[i]);
|
|
||||||
|
|
||||||
entries[i].key = (MetaTabEntryKey) workspace;
|
|
||||||
entries[i].title = meta_workspace_get_name (workspace);
|
|
||||||
entries[i].icon = NULL;
|
|
||||||
entries[i].blank = FALSE;
|
|
||||||
|
|
||||||
g_assert (entries[i].title != NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entries[i].key = NULL;
|
|
||||||
entries[i].title = NULL;
|
|
||||||
entries[i].icon = NULL;
|
|
||||||
entries[i].blank = TRUE;
|
|
||||||
}
|
|
||||||
entries[i].hidden = FALSE;
|
|
||||||
entries[i].demands_attention = FALSE;
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
screen->ws_popup = meta_ui_tab_popup_new (entries,
|
|
||||||
screen->number,
|
|
||||||
len,
|
|
||||||
layout.cols,
|
|
||||||
FALSE);
|
|
||||||
|
|
||||||
g_free (entries);
|
|
||||||
meta_screen_free_workspace_layout (&layout);
|
|
||||||
|
|
||||||
meta_ui_tab_popup_select (screen->ws_popup,
|
|
||||||
(MetaTabEntryKey) initial_selection);
|
|
||||||
meta_ui_tab_popup_set_showing (screen->ws_popup, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_screen_workspace_popup_select (MetaScreen *screen,
|
|
||||||
MetaWorkspace *workspace)
|
|
||||||
{
|
|
||||||
g_return_if_fail (screen->ws_popup != NULL);
|
|
||||||
|
|
||||||
meta_ui_tab_popup_select (screen->ws_popup,
|
|
||||||
(MetaTabEntryKey) workspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
MetaWorkspace *
|
|
||||||
meta_screen_workspace_popup_get_selected (MetaScreen *screen)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (screen->ws_popup != NULL, NULL);
|
|
||||||
|
|
||||||
return (MetaWorkspace *) meta_ui_tab_popup_get_selected (screen->ws_popup);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_screen_workspace_popup_destroy (MetaScreen *screen)
|
|
||||||
{
|
|
||||||
if (screen->ws_popup)
|
|
||||||
{
|
|
||||||
meta_ui_tab_popup_free (screen->ws_popup);
|
|
||||||
screen->ws_popup = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_screen_update_tile_preview_timeout (gpointer data)
|
meta_screen_update_tile_preview_timeout (gpointer data)
|
||||||
{
|
{
|
||||||
|
@@ -711,9 +711,7 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
|
|||||||
* XID => window table. (Wine uses a toplevel for _NET_WM_USER_TIME_WINDOW;
|
* 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.)
|
* see window-prop.c:reload_net_wm_user_time_window() for registration.)
|
||||||
*/
|
*/
|
||||||
if (meta_window &&
|
if (meta_window && windows[i] == meta_window->xwindow)
|
||||||
(windows[i] == meta_window->xwindow ||
|
|
||||||
(meta_window->frame && windows[i] == meta_window->frame->xwindow)))
|
|
||||||
meta_windows = g_list_prepend (meta_windows, meta_window);
|
meta_windows = g_list_prepend (meta_windows, meta_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1189,9 +1189,6 @@ stack_sync_to_server (MetaStack *stack)
|
|||||||
else
|
else
|
||||||
g_array_prepend_val (stacked, w->xwindow);
|
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
|
/* We don't restack hidden windows along with the rest, though they are
|
||||||
|
@@ -1705,13 +1705,6 @@ meta_window_unmanage (MetaWindow *window,
|
|||||||
meta_compositor_remove_window (window->display->compositor, 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)
|
if (destroying_windows_disallowed > 0)
|
||||||
meta_bug ("Tried to destroy window %s while destruction was not allowed\n",
|
meta_bug ("Tried to destroy window %s while destruction was not allowed\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
@@ -3697,10 +3690,6 @@ meta_window_tile (MetaWindow *window)
|
|||||||
window,
|
window,
|
||||||
&old_rect,
|
&old_rect,
|
||||||
&new_rect);
|
&new_rect);
|
||||||
|
|
||||||
if (window->frame)
|
|
||||||
meta_ui_queue_frame_draw (window->screen->ui,
|
|
||||||
window->frame->xwindow);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -7888,11 +7877,6 @@ meta_window_update_shape_region_x11 (MetaWindow *window)
|
|||||||
static void
|
static void
|
||||||
redraw_icon (MetaWindow *window)
|
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
|
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
|
void
|
||||||
meta_window_show_menu (MetaWindow *window,
|
meta_window_show_menu (MetaWindow *window,
|
||||||
int root_x,
|
int root_x,
|
||||||
@@ -8790,126 +8635,6 @@ meta_window_show_menu (MetaWindow *window,
|
|||||||
int button,
|
int button,
|
||||||
guint32 timestamp)
|
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
|
void
|
||||||
@@ -11245,13 +10970,7 @@ meta_window_get_frame_type (MetaWindow *window)
|
|||||||
cairo_region_t *
|
cairo_region_t *
|
||||||
meta_window_get_frame_bounds (MetaWindow *window)
|
meta_window_get_frame_bounds (MetaWindow *window)
|
||||||
{
|
{
|
||||||
if (!window->frame_bounds)
|
return NULL;
|
||||||
{
|
|
||||||
if (window->frame)
|
|
||||||
window->frame_bounds = meta_frame_get_frame_bounds (window->frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
return window->frame_bounds;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
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 <clutter/clutter.h>
|
||||||
#include <cogl/cogl.h>
|
#include <cogl/cogl.h>
|
||||||
|
|
||||||
#include <meta/gradient.h>
|
|
||||||
#include <meta/screen.h>
|
#include <meta/screen.h>
|
||||||
|
|
||||||
#include <gsettings-desktop-schemas/gdesktop-enums.h>
|
#include <gsettings-desktop-schemas/gdesktop-enums.h>
|
||||||
|
@@ -24,7 +24,6 @@
|
|||||||
#include <cogl/cogl.h>
|
#include <cogl/cogl.h>
|
||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
#include <meta/gradient.h>
|
|
||||||
#include <meta/screen.h>
|
#include <meta/screen.h>
|
||||||
|
|
||||||
#include <gsettings-desktop-schemas/gdesktop-enums.h>
|
#include <gsettings-desktop-schemas/gdesktop-enums.h>
|
||||||
|
@@ -43,7 +43,6 @@
|
|||||||
* @META_PREF_AUTO_RAISE: auto-raise
|
* @META_PREF_AUTO_RAISE: auto-raise
|
||||||
* @META_PREF_AUTO_RAISE_DELAY: auto-raise delay
|
* @META_PREF_AUTO_RAISE_DELAY: auto-raise delay
|
||||||
* @META_PREF_FOCUS_CHANGE_ON_POINTER_REST: focus change on pointer rest
|
* @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_TITLEBAR_FONT: title-bar font
|
||||||
* @META_PREF_NUM_WORKSPACES: number of workspaces
|
* @META_PREF_NUM_WORKSPACES: number of workspaces
|
||||||
* @META_PREF_DYNAMIC_WORKSPACES: dynamic workspaces
|
* @META_PREF_DYNAMIC_WORKSPACES: dynamic workspaces
|
||||||
@@ -62,7 +61,6 @@
|
|||||||
* @META_PREF_EDGE_TILING: edge tiling
|
* @META_PREF_EDGE_TILING: edge tiling
|
||||||
* @META_PREF_FORCE_FULLSCREEN: force fullscreen
|
* @META_PREF_FORCE_FULLSCREEN: force fullscreen
|
||||||
* @META_PREF_WORKSPACES_ONLY_ON_PRIMARY: workspaces only on primary
|
* @META_PREF_WORKSPACES_ONLY_ON_PRIMARY: workspaces only on primary
|
||||||
* @META_PREF_NO_TAB_POPUP: no tab popup
|
|
||||||
* @META_PREF_DRAGGABLE_BORDER_WIDTH: draggable border width
|
* @META_PREF_DRAGGABLE_BORDER_WIDTH: draggable border width
|
||||||
* @META_PREF_AUTO_MAXIMIZE: auto-maximize
|
* @META_PREF_AUTO_MAXIMIZE: auto-maximize
|
||||||
*/
|
*/
|
||||||
@@ -81,7 +79,6 @@ typedef enum
|
|||||||
META_PREF_AUTO_RAISE,
|
META_PREF_AUTO_RAISE,
|
||||||
META_PREF_AUTO_RAISE_DELAY,
|
META_PREF_AUTO_RAISE_DELAY,
|
||||||
META_PREF_FOCUS_CHANGE_ON_POINTER_REST,
|
META_PREF_FOCUS_CHANGE_ON_POINTER_REST,
|
||||||
META_PREF_THEME,
|
|
||||||
META_PREF_TITLEBAR_FONT,
|
META_PREF_TITLEBAR_FONT,
|
||||||
META_PREF_NUM_WORKSPACES,
|
META_PREF_NUM_WORKSPACES,
|
||||||
META_PREF_DYNAMIC_WORKSPACES,
|
META_PREF_DYNAMIC_WORKSPACES,
|
||||||
@@ -100,7 +97,6 @@ typedef enum
|
|||||||
META_PREF_EDGE_TILING,
|
META_PREF_EDGE_TILING,
|
||||||
META_PREF_FORCE_FULLSCREEN,
|
META_PREF_FORCE_FULLSCREEN,
|
||||||
META_PREF_WORKSPACES_ONLY_ON_PRIMARY,
|
META_PREF_WORKSPACES_ONLY_ON_PRIMARY,
|
||||||
META_PREF_NO_TAB_POPUP,
|
|
||||||
META_PREF_DRAGGABLE_BORDER_WIDTH,
|
META_PREF_DRAGGABLE_BORDER_WIDTH,
|
||||||
META_PREF_AUTO_MAXIMIZE
|
META_PREF_AUTO_MAXIMIZE
|
||||||
} MetaPreference;
|
} MetaPreference;
|
||||||
@@ -127,7 +123,6 @@ GDesktopFocusMode meta_prefs_get_focus_mode (void);
|
|||||||
GDesktopFocusNewWindows meta_prefs_get_focus_new_windows (void);
|
GDesktopFocusNewWindows meta_prefs_get_focus_new_windows (void);
|
||||||
gboolean meta_prefs_get_attach_modal_dialogs (void);
|
gboolean meta_prefs_get_attach_modal_dialogs (void);
|
||||||
gboolean meta_prefs_get_raise_on_click (void);
|
gboolean meta_prefs_get_raise_on_click (void);
|
||||||
const char* meta_prefs_get_theme (void);
|
|
||||||
/* returns NULL if GTK default should be used */
|
/* returns NULL if GTK default should be used */
|
||||||
const PangoFontDescription* meta_prefs_get_titlebar_font (void);
|
const PangoFontDescription* meta_prefs_get_titlebar_font (void);
|
||||||
int meta_prefs_get_num_workspaces (void);
|
int meta_prefs_get_num_workspaces (void);
|
||||||
@@ -163,9 +158,6 @@ void meta_prefs_set_force_fullscreen (gboolean whether);
|
|||||||
|
|
||||||
gboolean meta_prefs_get_workspaces_only_on_primary (void);
|
gboolean meta_prefs_get_workspaces_only_on_primary (void);
|
||||||
|
|
||||||
gboolean meta_prefs_get_no_tab_popup (void);
|
|
||||||
void meta_prefs_set_no_tab_popup (gboolean whether);
|
|
||||||
|
|
||||||
int meta_prefs_get_draggable_border_width (void);
|
int meta_prefs_get_draggable_border_width (void);
|
||||||
|
|
||||||
gboolean meta_prefs_get_ignore_request_hide_titlebar (void);
|
gboolean meta_prefs_get_ignore_request_hide_titlebar (void);
|
||||||
@@ -204,8 +196,6 @@ void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether);
|
|||||||
* @META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD: FILLME
|
* @META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD: FILLME
|
||||||
* @META_KEYBINDING_ACTION_CYCLE_PANELS: FILLME
|
* @META_KEYBINDING_ACTION_CYCLE_PANELS: FILLME
|
||||||
* @META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD: FILLME
|
* @META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD: FILLME
|
||||||
* @META_KEYBINDING_ACTION_TAB_POPUP_SELECT: FILLME
|
|
||||||
* @META_KEYBINDING_ACTION_TAB_POPUP_CANCEL: FILLME
|
|
||||||
* @META_KEYBINDING_ACTION_SHOW_DESKTOP: FILLME
|
* @META_KEYBINDING_ACTION_SHOW_DESKTOP: FILLME
|
||||||
* @META_KEYBINDING_ACTION_PANEL_MAIN_MENU: FILLME
|
* @META_KEYBINDING_ACTION_PANEL_MAIN_MENU: FILLME
|
||||||
* @META_KEYBINDING_ACTION_PANEL_RUN_DIALOG: FILLME
|
* @META_KEYBINDING_ACTION_PANEL_RUN_DIALOG: FILLME
|
||||||
@@ -301,8 +291,6 @@ typedef enum _MetaKeyBindingAction
|
|||||||
META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD,
|
META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD,
|
||||||
META_KEYBINDING_ACTION_CYCLE_PANELS,
|
META_KEYBINDING_ACTION_CYCLE_PANELS,
|
||||||
META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD,
|
META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD,
|
||||||
META_KEYBINDING_ACTION_TAB_POPUP_SELECT,
|
|
||||||
META_KEYBINDING_ACTION_TAB_POPUP_CANCEL,
|
|
||||||
META_KEYBINDING_ACTION_SHOW_DESKTOP,
|
META_KEYBINDING_ACTION_SHOW_DESKTOP,
|
||||||
META_KEYBINDING_ACTION_PANEL_MAIN_MENU,
|
META_KEYBINDING_ACTION_PANEL_MAIN_MENU,
|
||||||
META_KEYBINDING_ACTION_PANEL_RUN_DIALOG,
|
META_KEYBINDING_ACTION_PANEL_RUN_DIALOG,
|
||||||
|
@@ -111,7 +111,6 @@ gint meta_unsigned_long_equal (gconstpointer v1,
|
|||||||
gconstpointer v2);
|
gconstpointer v2);
|
||||||
guint meta_unsigned_long_hash (gconstpointer v);
|
guint meta_unsigned_long_hash (gconstpointer v);
|
||||||
|
|
||||||
const char* meta_frame_type_to_string (MetaFrameType type);
|
|
||||||
const char* meta_gravity_to_string (int gravity);
|
const char* meta_gravity_to_string (int gravity);
|
||||||
|
|
||||||
char* meta_external_binding_name_for_action (guint keybinding_action);
|
char* meta_external_binding_name_for_action (guint keybinding_action);
|
||||||
|
@@ -1,224 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
|
|
||||||
/* Draw a workspace */
|
|
||||||
|
|
||||||
/* This file should not be modified to depend on other files in
|
|
||||||
* libwnck or mutter, since it's used in both of them
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2002 Red Hat Inc.
|
|
||||||
*
|
|
||||||
* 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 "draw-workspace.h"
|
|
||||||
#include "theme-private.h"
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
get_window_rect (const WnckWindowDisplayInfo *win,
|
|
||||||
int screen_width,
|
|
||||||
int screen_height,
|
|
||||||
const GdkRectangle *workspace_rect,
|
|
||||||
GdkRectangle *rect)
|
|
||||||
{
|
|
||||||
double width_ratio, height_ratio;
|
|
||||||
int x, y, width, height;
|
|
||||||
|
|
||||||
width_ratio = (double) workspace_rect->width / (double) screen_width;
|
|
||||||
height_ratio = (double) workspace_rect->height / (double) screen_height;
|
|
||||||
|
|
||||||
x = win->x;
|
|
||||||
y = win->y;
|
|
||||||
width = win->width;
|
|
||||||
height = win->height;
|
|
||||||
|
|
||||||
x *= width_ratio;
|
|
||||||
y *= height_ratio;
|
|
||||||
width *= width_ratio;
|
|
||||||
height *= height_ratio;
|
|
||||||
|
|
||||||
x += workspace_rect->x;
|
|
||||||
y += workspace_rect->y;
|
|
||||||
|
|
||||||
if (width < 3)
|
|
||||||
width = 3;
|
|
||||||
if (height < 3)
|
|
||||||
height = 3;
|
|
||||||
|
|
||||||
rect->x = x;
|
|
||||||
rect->y = y;
|
|
||||||
rect->width = width;
|
|
||||||
rect->height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
draw_window (GtkWidget *widget,
|
|
||||||
cairo_t *cr,
|
|
||||||
const WnckWindowDisplayInfo *win,
|
|
||||||
const GdkRectangle *winrect,
|
|
||||||
GtkStateFlags state)
|
|
||||||
{
|
|
||||||
GdkPixbuf *icon;
|
|
||||||
int icon_x, icon_y, icon_w, icon_h;
|
|
||||||
gboolean is_active;
|
|
||||||
GdkRGBA color;
|
|
||||||
GtkStyleContext *style;
|
|
||||||
|
|
||||||
is_active = win->is_active;
|
|
||||||
|
|
||||||
cairo_save (cr);
|
|
||||||
|
|
||||||
cairo_rectangle (cr, winrect->x, winrect->y, winrect->width, winrect->height);
|
|
||||||
cairo_clip (cr);
|
|
||||||
|
|
||||||
style = gtk_widget_get_style_context (widget);
|
|
||||||
if (is_active)
|
|
||||||
meta_gtk_style_get_light_color (style, state, &color);
|
|
||||||
else
|
|
||||||
gtk_style_context_get_background_color (style, state, &color);
|
|
||||||
gdk_cairo_set_source_rgba (cr, &color);
|
|
||||||
|
|
||||||
cairo_rectangle (cr,
|
|
||||||
winrect->x + 1, winrect->y + 1,
|
|
||||||
MAX (0, winrect->width - 2), MAX (0, winrect->height - 2));
|
|
||||||
cairo_fill (cr);
|
|
||||||
|
|
||||||
|
|
||||||
icon = win->icon;
|
|
||||||
|
|
||||||
icon_w = icon_h = 0;
|
|
||||||
|
|
||||||
if (icon)
|
|
||||||
{
|
|
||||||
icon_w = gdk_pixbuf_get_width (icon);
|
|
||||||
icon_h = gdk_pixbuf_get_height (icon);
|
|
||||||
|
|
||||||
/* If the icon is too big, fall back to mini icon.
|
|
||||||
* We don't arbitrarily scale the icon, because it's
|
|
||||||
* just too slow on my Athlon 850.
|
|
||||||
*/
|
|
||||||
if (icon_w > (winrect->width - 2) ||
|
|
||||||
icon_h > (winrect->height - 2))
|
|
||||||
{
|
|
||||||
icon = win->mini_icon;
|
|
||||||
if (icon)
|
|
||||||
{
|
|
||||||
icon_w = gdk_pixbuf_get_width (icon);
|
|
||||||
icon_h = gdk_pixbuf_get_height (icon);
|
|
||||||
|
|
||||||
/* Give up. */
|
|
||||||
if (icon_w > (winrect->width - 2) ||
|
|
||||||
icon_h > (winrect->height - 2))
|
|
||||||
icon = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (icon)
|
|
||||||
{
|
|
||||||
icon_x = winrect->x + (winrect->width - icon_w) / 2;
|
|
||||||
icon_y = winrect->y + (winrect->height - icon_h) / 2;
|
|
||||||
|
|
||||||
cairo_save (cr);
|
|
||||||
gdk_cairo_set_source_pixbuf (cr, icon, icon_x, icon_y);
|
|
||||||
cairo_rectangle (cr, icon_x, icon_y, icon_w, icon_h);
|
|
||||||
cairo_clip (cr);
|
|
||||||
cairo_paint (cr);
|
|
||||||
cairo_restore (cr);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_style_context_get_color (style, state, &color);
|
|
||||||
gdk_cairo_set_source_rgba (cr, &color);
|
|
||||||
cairo_set_line_width (cr, 1.0);
|
|
||||||
cairo_rectangle (cr,
|
|
||||||
winrect->x + 0.5, winrect->y + 0.5,
|
|
||||||
MAX (0, winrect->width - 1), MAX (0, winrect->height - 1));
|
|
||||||
cairo_stroke (cr);
|
|
||||||
|
|
||||||
cairo_restore (cr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
wnck_draw_workspace (GtkWidget *widget,
|
|
||||||
cairo_t *cr,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int screen_width,
|
|
||||||
int screen_height,
|
|
||||||
GdkPixbuf *workspace_background,
|
|
||||||
gboolean is_active,
|
|
||||||
const WnckWindowDisplayInfo *windows,
|
|
||||||
int n_windows)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
GdkRectangle workspace_rect;
|
|
||||||
GtkStateFlags state;
|
|
||||||
GtkStyleContext *style;
|
|
||||||
|
|
||||||
workspace_rect.x = x;
|
|
||||||
workspace_rect.y = y;
|
|
||||||
workspace_rect.width = width;
|
|
||||||
workspace_rect.height = height;
|
|
||||||
|
|
||||||
if (is_active)
|
|
||||||
state = GTK_STATE_FLAG_SELECTED;
|
|
||||||
else if (workspace_background)
|
|
||||||
state = GTK_STATE_FLAG_PRELIGHT;
|
|
||||||
else
|
|
||||||
state = GTK_STATE_FLAG_NORMAL;
|
|
||||||
|
|
||||||
style = gtk_widget_get_style_context (widget);
|
|
||||||
|
|
||||||
cairo_save (cr);
|
|
||||||
|
|
||||||
if (workspace_background)
|
|
||||||
{
|
|
||||||
gdk_cairo_set_source_pixbuf (cr, workspace_background, x, y);
|
|
||||||
cairo_paint (cr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GdkRGBA color;
|
|
||||||
|
|
||||||
meta_gtk_style_get_dark_color (style,state, &color);
|
|
||||||
gdk_cairo_set_source_rgba (cr, &color);
|
|
||||||
cairo_rectangle (cr, x, y, width, height);
|
|
||||||
cairo_fill (cr);
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (i < n_windows)
|
|
||||||
{
|
|
||||||
const WnckWindowDisplayInfo *win = &windows[i];
|
|
||||||
GdkRectangle winrect;
|
|
||||||
|
|
||||||
get_window_rect (win, screen_width,
|
|
||||||
screen_height, &workspace_rect, &winrect);
|
|
||||||
|
|
||||||
draw_window (widget,
|
|
||||||
cr,
|
|
||||||
win,
|
|
||||||
&winrect,
|
|
||||||
state);
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_restore (cr);
|
|
||||||
|
|
||||||
}
|
|
@@ -1,59 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
|
|
||||||
/* Draw a workspace */
|
|
||||||
|
|
||||||
/* This file should not be modified to depend on other files in
|
|
||||||
* libwnck or metacity, since it's used in both of them
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2002 Red Hat Inc.
|
|
||||||
*
|
|
||||||
* 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 WNCK_DRAW_WORKSPACE_H
|
|
||||||
#define WNCK_DRAW_WORKSPACE_H
|
|
||||||
|
|
||||||
#include <gdk/gdk.h>
|
|
||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GdkPixbuf *icon;
|
|
||||||
GdkPixbuf *mini_icon;
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
|
|
||||||
guint is_active : 1;
|
|
||||||
|
|
||||||
} WnckWindowDisplayInfo;
|
|
||||||
|
|
||||||
void wnck_draw_workspace (GtkWidget *widget,
|
|
||||||
cairo_t *cr,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int screen_width,
|
|
||||||
int screen_height,
|
|
||||||
GdkPixbuf *workspace_background,
|
|
||||||
gboolean is_active,
|
|
||||||
const WnckWindowDisplayInfo *windows,
|
|
||||||
int n_windows);
|
|
||||||
|
|
||||||
#endif
|
|
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,963 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
|
|
||||||
/* Mutter popup window thing showing windows you can tab to */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2001 Havoc Pennington
|
|
||||||
* Copyright (C) 2002 Red Hat, Inc.
|
|
||||||
* 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 <meta/util.h>
|
|
||||||
#include "core.h"
|
|
||||||
#include "tabpopup.h"
|
|
||||||
/* FIXME these two includes are 100% broken ...
|
|
||||||
*/
|
|
||||||
#include "workspace-private.h"
|
|
||||||
#include "frame.h"
|
|
||||||
#include "draw-workspace.h"
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#define OUTSIDE_SELECT_RECT 2
|
|
||||||
#define INSIDE_SELECT_RECT 2
|
|
||||||
|
|
||||||
typedef struct _TabEntry TabEntry;
|
|
||||||
|
|
||||||
struct _TabEntry
|
|
||||||
{
|
|
||||||
MetaTabEntryKey key;
|
|
||||||
char *title;
|
|
||||||
GdkPixbuf *icon, *dimmed_icon;
|
|
||||||
GtkWidget *widget;
|
|
||||||
GdkRectangle rect;
|
|
||||||
GdkRectangle inner_rect;
|
|
||||||
guint blank : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _MetaTabPopup
|
|
||||||
{
|
|
||||||
GtkWidget *window;
|
|
||||||
GtkWidget *label;
|
|
||||||
GList *current;
|
|
||||||
GList *entries;
|
|
||||||
TabEntry *current_selected_entry;
|
|
||||||
GtkWidget *outline_window;
|
|
||||||
gboolean outline;
|
|
||||||
};
|
|
||||||
|
|
||||||
static GtkWidget* selectable_image_new (GdkPixbuf *pixbuf);
|
|
||||||
static void select_image (GtkWidget *widget);
|
|
||||||
static void unselect_image (GtkWidget *widget);
|
|
||||||
|
|
||||||
static GtkWidget* selectable_workspace_new (MetaWorkspace *workspace);
|
|
||||||
static void select_workspace (GtkWidget *widget);
|
|
||||||
static void unselect_workspace (GtkWidget *widget);
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
outline_window_draw (GtkWidget *widget,
|
|
||||||
cairo_t *cr,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
MetaTabPopup *popup;
|
|
||||||
TabEntry *te;
|
|
||||||
|
|
||||||
popup = data;
|
|
||||||
|
|
||||||
if (!popup->outline || popup->current_selected_entry == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
te = popup->current_selected_entry;
|
|
||||||
|
|
||||||
cairo_set_line_width (cr, 1.0);
|
|
||||||
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
|
|
||||||
|
|
||||||
cairo_rectangle (cr,
|
|
||||||
0.5, 0.5,
|
|
||||||
te->rect.width - 1,
|
|
||||||
te->rect.height - 1);
|
|
||||||
cairo_stroke (cr);
|
|
||||||
|
|
||||||
cairo_rectangle (cr,
|
|
||||||
te->inner_rect.x - 0.5, te->inner_rect.y - 0.5,
|
|
||||||
te->inner_rect.width + 1,
|
|
||||||
te->inner_rect.height + 1);
|
|
||||||
cairo_stroke (cr);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GdkPixbuf*
|
|
||||||
dimm_icon (GdkPixbuf *pixbuf)
|
|
||||||
{
|
|
||||||
int x, y, pixel_stride, row_stride;
|
|
||||||
guchar *row, *pixels;
|
|
||||||
int w, h;
|
|
||||||
GdkPixbuf *dimmed_pixbuf;
|
|
||||||
|
|
||||||
if (gdk_pixbuf_get_has_alpha (pixbuf))
|
|
||||||
{
|
|
||||||
dimmed_pixbuf = gdk_pixbuf_copy (pixbuf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dimmed_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
w = gdk_pixbuf_get_width (dimmed_pixbuf);
|
|
||||||
h = gdk_pixbuf_get_height (dimmed_pixbuf);
|
|
||||||
|
|
||||||
pixel_stride = 4;
|
|
||||||
|
|
||||||
row = gdk_pixbuf_get_pixels (dimmed_pixbuf);
|
|
||||||
row_stride = gdk_pixbuf_get_rowstride (dimmed_pixbuf);
|
|
||||||
|
|
||||||
for (y = 0; y < h; y++)
|
|
||||||
{
|
|
||||||
pixels = row;
|
|
||||||
for (x = 0; x < w; x++)
|
|
||||||
{
|
|
||||||
pixels[3] /= 2;
|
|
||||||
pixels += pixel_stride;
|
|
||||||
}
|
|
||||||
row += row_stride;
|
|
||||||
}
|
|
||||||
return dimmed_pixbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static TabEntry*
|
|
||||||
tab_entry_new (const MetaTabEntry *entry,
|
|
||||||
gint screen_width,
|
|
||||||
gboolean outline)
|
|
||||||
{
|
|
||||||
TabEntry *te;
|
|
||||||
|
|
||||||
te = g_new (TabEntry, 1);
|
|
||||||
te->key = entry->key;
|
|
||||||
te->title = NULL;
|
|
||||||
if (entry->title)
|
|
||||||
{
|
|
||||||
gchar *str;
|
|
||||||
gchar *tmp;
|
|
||||||
gchar *formatter = "%s";
|
|
||||||
|
|
||||||
str = meta_g_utf8_strndup (entry->title, 4096);
|
|
||||||
|
|
||||||
if (entry->hidden)
|
|
||||||
{
|
|
||||||
formatter = "[%s]";
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = g_markup_printf_escaped (formatter, str);
|
|
||||||
g_free (str);
|
|
||||||
str = tmp;
|
|
||||||
|
|
||||||
if (entry->demands_attention)
|
|
||||||
{
|
|
||||||
/* Escape the whole line of text then markup the text and
|
|
||||||
* copy it back into the original buffer.
|
|
||||||
*/
|
|
||||||
tmp = g_strdup_printf ("<b>%s</b>", str);
|
|
||||||
g_free (str);
|
|
||||||
str = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
te->title=g_strdup(str);
|
|
||||||
|
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
te->widget = NULL;
|
|
||||||
te->icon = entry->icon;
|
|
||||||
te->blank = entry->blank;
|
|
||||||
te->dimmed_icon = NULL;
|
|
||||||
if (te->icon)
|
|
||||||
{
|
|
||||||
g_object_ref (G_OBJECT (te->icon));
|
|
||||||
if (entry->hidden)
|
|
||||||
te->dimmed_icon = dimm_icon (entry->icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outline)
|
|
||||||
{
|
|
||||||
te->rect.x = entry->rect.x;
|
|
||||||
te->rect.y = entry->rect.y;
|
|
||||||
te->rect.width = entry->rect.width;
|
|
||||||
te->rect.height = entry->rect.height;
|
|
||||||
|
|
||||||
te->inner_rect.x = entry->inner_rect.x;
|
|
||||||
te->inner_rect.y = entry->inner_rect.y;
|
|
||||||
te->inner_rect.width = entry->inner_rect.width;
|
|
||||||
te->inner_rect.height = entry->inner_rect.height;
|
|
||||||
}
|
|
||||||
return te;
|
|
||||||
}
|
|
||||||
|
|
||||||
MetaTabPopup*
|
|
||||||
meta_ui_tab_popup_new (const MetaTabEntry *entries,
|
|
||||||
int screen_number,
|
|
||||||
int entry_count,
|
|
||||||
int width,
|
|
||||||
gboolean outline)
|
|
||||||
{
|
|
||||||
MetaTabPopup *popup;
|
|
||||||
int i, left, top;
|
|
||||||
int height;
|
|
||||||
GtkWidget *grid;
|
|
||||||
GtkWidget *vbox;
|
|
||||||
GtkWidget *align;
|
|
||||||
GList *tmp;
|
|
||||||
GtkWidget *frame;
|
|
||||||
int max_label_width; /* the actual max width of the labels we create */
|
|
||||||
AtkObject *obj;
|
|
||||||
GdkScreen *screen;
|
|
||||||
int screen_width;
|
|
||||||
|
|
||||||
popup = g_new (MetaTabPopup, 1);
|
|
||||||
|
|
||||||
popup->outline_window = gtk_window_new (GTK_WINDOW_POPUP);
|
|
||||||
|
|
||||||
screen = gdk_display_get_screen (gdk_display_get_default (),
|
|
||||||
screen_number);
|
|
||||||
gtk_window_set_screen (GTK_WINDOW (popup->outline_window),
|
|
||||||
screen);
|
|
||||||
|
|
||||||
gtk_widget_set_app_paintable (popup->outline_window, TRUE);
|
|
||||||
gtk_widget_realize (popup->outline_window);
|
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT (popup->outline_window), "draw",
|
|
||||||
G_CALLBACK (outline_window_draw), popup);
|
|
||||||
|
|
||||||
popup->window = gtk_window_new (GTK_WINDOW_POPUP);
|
|
||||||
|
|
||||||
gtk_window_set_screen (GTK_WINDOW (popup->window),
|
|
||||||
screen);
|
|
||||||
|
|
||||||
gtk_window_set_position (GTK_WINDOW (popup->window),
|
|
||||||
GTK_WIN_POS_CENTER_ALWAYS);
|
|
||||||
/* enable resizing, to get never-shrink behavior */
|
|
||||||
gtk_window_set_resizable (GTK_WINDOW (popup->window),
|
|
||||||
TRUE);
|
|
||||||
popup->current = NULL;
|
|
||||||
popup->entries = NULL;
|
|
||||||
popup->current_selected_entry = NULL;
|
|
||||||
popup->outline = outline;
|
|
||||||
|
|
||||||
screen_width = gdk_screen_get_width (screen);
|
|
||||||
for (i = 0; i < entry_count; ++i)
|
|
||||||
{
|
|
||||||
TabEntry* new_entry = tab_entry_new (&entries[i], screen_width, outline);
|
|
||||||
popup->entries = g_list_prepend (popup->entries, new_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
popup->entries = g_list_reverse (popup->entries);
|
|
||||||
|
|
||||||
g_assert (width > 0);
|
|
||||||
height = i / width;
|
|
||||||
if (i % width)
|
|
||||||
height += 1;
|
|
||||||
|
|
||||||
grid = gtk_grid_new ();
|
|
||||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
|
||||||
|
|
||||||
frame = gtk_frame_new (NULL);
|
|
||||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
|
|
||||||
gtk_container_set_border_width (GTK_CONTAINER (grid), 1);
|
|
||||||
gtk_container_add (GTK_CONTAINER (popup->window),
|
|
||||||
frame);
|
|
||||||
gtk_container_add (GTK_CONTAINER (frame),
|
|
||||||
vbox);
|
|
||||||
|
|
||||||
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
|
|
||||||
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0);
|
|
||||||
|
|
||||||
gtk_container_add (GTK_CONTAINER (align),
|
|
||||||
grid);
|
|
||||||
|
|
||||||
popup->label = gtk_label_new ("");
|
|
||||||
|
|
||||||
/* Set the accessible role of the label to a status bar so it
|
|
||||||
* will emit name changed events that can be used by screen
|
|
||||||
* readers.
|
|
||||||
*/
|
|
||||||
obj = gtk_widget_get_accessible (popup->label);
|
|
||||||
atk_object_set_role (obj, ATK_ROLE_STATUSBAR);
|
|
||||||
|
|
||||||
gtk_misc_set_padding (GTK_MISC (popup->label), 3, 3);
|
|
||||||
|
|
||||||
gtk_box_pack_end (GTK_BOX (vbox), popup->label, FALSE, FALSE, 0);
|
|
||||||
|
|
||||||
max_label_width = 0;
|
|
||||||
top = 0;
|
|
||||||
tmp = popup->entries;
|
|
||||||
|
|
||||||
while (tmp && top < height)
|
|
||||||
{
|
|
||||||
left = 0;
|
|
||||||
|
|
||||||
while (tmp && left < width)
|
|
||||||
{
|
|
||||||
GtkWidget *image;
|
|
||||||
GtkRequisition req;
|
|
||||||
|
|
||||||
TabEntry *te;
|
|
||||||
|
|
||||||
te = tmp->data;
|
|
||||||
|
|
||||||
if (te->blank)
|
|
||||||
{
|
|
||||||
/* just stick a widget here to avoid special cases */
|
|
||||||
image = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
|
|
||||||
}
|
|
||||||
else if (outline)
|
|
||||||
{
|
|
||||||
if (te->dimmed_icon)
|
|
||||||
{
|
|
||||||
image = selectable_image_new (te->dimmed_icon);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
image = selectable_image_new (te->icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_misc_set_padding (GTK_MISC (image),
|
|
||||||
INSIDE_SELECT_RECT + OUTSIDE_SELECT_RECT + 1,
|
|
||||||
INSIDE_SELECT_RECT + OUTSIDE_SELECT_RECT + 1);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.5);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
image = selectable_workspace_new ((MetaWorkspace *) te->key);
|
|
||||||
}
|
|
||||||
|
|
||||||
te->widget = image;
|
|
||||||
|
|
||||||
gtk_grid_attach (GTK_GRID (grid),
|
|
||||||
te->widget,
|
|
||||||
left, top, 1, 1);
|
|
||||||
|
|
||||||
/* Efficiency rules! */
|
|
||||||
gtk_label_set_markup (GTK_LABEL (popup->label),
|
|
||||||
te->title);
|
|
||||||
gtk_widget_get_preferred_size (popup->label, &req, NULL);
|
|
||||||
max_label_width = MAX (max_label_width, req.width);
|
|
||||||
|
|
||||||
tmp = tmp->next;
|
|
||||||
|
|
||||||
++left;
|
|
||||||
}
|
|
||||||
|
|
||||||
++top;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove all the temporary text */
|
|
||||||
gtk_label_set_text (GTK_LABEL (popup->label), "");
|
|
||||||
/* Make it so that we ellipsize if the text is too long */
|
|
||||||
gtk_label_set_ellipsize (GTK_LABEL (popup->label), PANGO_ELLIPSIZE_END);
|
|
||||||
|
|
||||||
/* Limit the window size to no bigger than screen_width/4 */
|
|
||||||
if (max_label_width>(screen_width/4))
|
|
||||||
{
|
|
||||||
max_label_width = screen_width/4;
|
|
||||||
}
|
|
||||||
|
|
||||||
max_label_width += 20; /* add random padding */
|
|
||||||
|
|
||||||
gtk_window_set_default_size (GTK_WINDOW (popup->window),
|
|
||||||
max_label_width,
|
|
||||||
-1);
|
|
||||||
|
|
||||||
return popup;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
free_tab_entry (gpointer data, gpointer user_data)
|
|
||||||
{
|
|
||||||
TabEntry *te;
|
|
||||||
|
|
||||||
te = data;
|
|
||||||
|
|
||||||
g_free (te->title);
|
|
||||||
if (te->icon)
|
|
||||||
g_object_unref (G_OBJECT (te->icon));
|
|
||||||
if (te->dimmed_icon)
|
|
||||||
g_object_unref (G_OBJECT (te->dimmed_icon));
|
|
||||||
|
|
||||||
g_free (te);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_ui_tab_popup_free (MetaTabPopup *popup)
|
|
||||||
{
|
|
||||||
meta_verbose ("Destroying tab popup window\n");
|
|
||||||
|
|
||||||
if (!popup)
|
|
||||||
{
|
|
||||||
meta_warning ("NULL passed to meta_ui_tab_popup_free\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_widget_destroy (popup->outline_window);
|
|
||||||
gtk_widget_destroy (popup->window);
|
|
||||||
|
|
||||||
g_list_foreach (popup->entries, free_tab_entry, NULL);
|
|
||||||
|
|
||||||
g_list_free (popup->entries);
|
|
||||||
|
|
||||||
g_free (popup);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_ui_tab_popup_set_showing (MetaTabPopup *popup,
|
|
||||||
gboolean showing)
|
|
||||||
{
|
|
||||||
if (showing)
|
|
||||||
{
|
|
||||||
gtk_widget_show_all (popup->window);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (gtk_widget_get_visible (popup->window))
|
|
||||||
{
|
|
||||||
meta_verbose ("Hiding tab popup window\n");
|
|
||||||
gtk_widget_hide (popup->window);
|
|
||||||
meta_core_increment_event_serial (
|
|
||||||
GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
display_entry (MetaTabPopup *popup,
|
|
||||||
TabEntry *te)
|
|
||||||
{
|
|
||||||
GdkRectangle rect;
|
|
||||||
GdkWindow *window;
|
|
||||||
|
|
||||||
|
|
||||||
if (popup->current_selected_entry)
|
|
||||||
{
|
|
||||||
if (popup->outline)
|
|
||||||
unselect_image (popup->current_selected_entry->widget);
|
|
||||||
else
|
|
||||||
unselect_workspace (popup->current_selected_entry->widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_label_set_markup (GTK_LABEL (popup->label), te->title);
|
|
||||||
|
|
||||||
if (popup->outline)
|
|
||||||
select_image (te->widget);
|
|
||||||
else
|
|
||||||
select_workspace (te->widget);
|
|
||||||
|
|
||||||
if (popup->outline)
|
|
||||||
{
|
|
||||||
cairo_region_t *region;
|
|
||||||
cairo_region_t *inner_region;
|
|
||||||
GdkRGBA black = { 0.0, 0.0, 0.0, 1.0 };
|
|
||||||
|
|
||||||
window = gtk_widget_get_window (popup->outline_window);
|
|
||||||
|
|
||||||
/* Do stuff behind gtk's back */
|
|
||||||
gdk_window_hide (window);
|
|
||||||
meta_core_increment_event_serial (
|
|
||||||
GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
|
|
||||||
|
|
||||||
rect = te->rect;
|
|
||||||
rect.x = 0;
|
|
||||||
rect.y = 0;
|
|
||||||
|
|
||||||
gdk_window_move_resize (window,
|
|
||||||
te->rect.x, te->rect.y,
|
|
||||||
te->rect.width, te->rect.height);
|
|
||||||
|
|
||||||
gdk_window_set_background_rgba (window, &black);
|
|
||||||
|
|
||||||
|
|
||||||
region = cairo_region_create_rectangle (&rect);
|
|
||||||
inner_region = cairo_region_create_rectangle (&te->inner_rect);
|
|
||||||
cairo_region_subtract (region, inner_region);
|
|
||||||
cairo_region_destroy (inner_region);
|
|
||||||
|
|
||||||
gdk_window_shape_combine_region (window,
|
|
||||||
region,
|
|
||||||
0, 0);
|
|
||||||
|
|
||||||
cairo_region_destroy (region);
|
|
||||||
|
|
||||||
|
|
||||||
/* This should piss off gtk a bit, but we don't want to raise
|
|
||||||
* above the tab popup. So, instead of calling gtk_widget_show,
|
|
||||||
* we manually set the window as mapped and then manually map it
|
|
||||||
* with gdk functions.
|
|
||||||
*/
|
|
||||||
gtk_widget_set_mapped (popup->outline_window, TRUE);
|
|
||||||
gdk_window_show_unraised (window);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Must be before we handle an expose for the outline window */
|
|
||||||
popup->current_selected_entry = te;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_ui_tab_popup_forward (MetaTabPopup *popup)
|
|
||||||
{
|
|
||||||
if (popup->current != NULL)
|
|
||||||
popup->current = popup->current->next;
|
|
||||||
|
|
||||||
if (popup->current == NULL)
|
|
||||||
popup->current = popup->entries;
|
|
||||||
|
|
||||||
if (popup->current != NULL)
|
|
||||||
{
|
|
||||||
TabEntry *te;
|
|
||||||
|
|
||||||
te = popup->current->data;
|
|
||||||
|
|
||||||
display_entry (popup, te);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_ui_tab_popup_backward (MetaTabPopup *popup)
|
|
||||||
{
|
|
||||||
if (popup->current != NULL)
|
|
||||||
popup->current = popup->current->prev;
|
|
||||||
|
|
||||||
if (popup->current == NULL)
|
|
||||||
popup->current = g_list_last (popup->entries);
|
|
||||||
|
|
||||||
if (popup->current != NULL)
|
|
||||||
{
|
|
||||||
TabEntry *te;
|
|
||||||
|
|
||||||
te = popup->current->data;
|
|
||||||
|
|
||||||
display_entry (popup, te);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MetaTabEntryKey
|
|
||||||
meta_ui_tab_popup_get_selected (MetaTabPopup *popup)
|
|
||||||
{
|
|
||||||
if (popup->current)
|
|
||||||
{
|
|
||||||
TabEntry *te;
|
|
||||||
|
|
||||||
te = popup->current->data;
|
|
||||||
|
|
||||||
return te->key;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return (MetaTabEntryKey)None;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_ui_tab_popup_select (MetaTabPopup *popup,
|
|
||||||
MetaTabEntryKey key)
|
|
||||||
{
|
|
||||||
GList *tmp;
|
|
||||||
|
|
||||||
/* Note, "key" may not be in the list of entries; other code assumes
|
|
||||||
* it's OK to pass in a key that isn't.
|
|
||||||
*/
|
|
||||||
|
|
||||||
tmp = popup->entries;
|
|
||||||
while (tmp != NULL)
|
|
||||||
{
|
|
||||||
TabEntry *te;
|
|
||||||
|
|
||||||
te = tmp->data;
|
|
||||||
|
|
||||||
if (te->key == key)
|
|
||||||
{
|
|
||||||
popup->current = tmp;
|
|
||||||
|
|
||||||
display_entry (popup, te);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define META_TYPE_SELECT_IMAGE (meta_select_image_get_type ())
|
|
||||||
#define META_SELECT_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SELECT_IMAGE, MetaSelectImage))
|
|
||||||
|
|
||||||
typedef struct _MetaSelectImage MetaSelectImage;
|
|
||||||
typedef struct _MetaSelectImageClass MetaSelectImageClass;
|
|
||||||
|
|
||||||
struct _MetaSelectImage
|
|
||||||
{
|
|
||||||
GtkImage parent_instance;
|
|
||||||
guint selected : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _MetaSelectImageClass
|
|
||||||
{
|
|
||||||
GtkImageClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static GType meta_select_image_get_type (void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
static GtkWidget*
|
|
||||||
selectable_image_new (GdkPixbuf *pixbuf)
|
|
||||||
{
|
|
||||||
GtkWidget *w;
|
|
||||||
|
|
||||||
w = g_object_new (meta_select_image_get_type (), NULL);
|
|
||||||
gtk_image_set_from_pixbuf (GTK_IMAGE (w), pixbuf);
|
|
||||||
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
select_image (GtkWidget *widget)
|
|
||||||
{
|
|
||||||
META_SELECT_IMAGE (widget)->selected = TRUE;
|
|
||||||
gtk_widget_queue_draw (widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
unselect_image (GtkWidget *widget)
|
|
||||||
{
|
|
||||||
META_SELECT_IMAGE (widget)->selected = FALSE;
|
|
||||||
gtk_widget_queue_draw (widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void meta_select_image_class_init (MetaSelectImageClass *klass);
|
|
||||||
static gboolean meta_select_image_draw (GtkWidget *widget,
|
|
||||||
cairo_t *cr);
|
|
||||||
|
|
||||||
static GtkImageClass *parent_class;
|
|
||||||
|
|
||||||
GType
|
|
||||||
meta_select_image_get_type (void)
|
|
||||||
{
|
|
||||||
static GType image_type = 0;
|
|
||||||
|
|
||||||
if (!image_type)
|
|
||||||
{
|
|
||||||
static const GTypeInfo image_info =
|
|
||||||
{
|
|
||||||
sizeof (MetaSelectImageClass),
|
|
||||||
NULL, /* base_init */
|
|
||||||
NULL, /* base_finalize */
|
|
||||||
(GClassInitFunc) meta_select_image_class_init,
|
|
||||||
NULL, /* class_finalize */
|
|
||||||
NULL, /* class_data */
|
|
||||||
sizeof (MetaSelectImage),
|
|
||||||
16, /* n_preallocs */
|
|
||||||
(GInstanceInitFunc) NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
image_type = g_type_register_static (GTK_TYPE_IMAGE, "MetaSelectImage", &image_info, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return image_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_select_image_class_init (MetaSelectImageClass *klass)
|
|
||||||
{
|
|
||||||
GtkWidgetClass *widget_class;
|
|
||||||
|
|
||||||
parent_class = g_type_class_peek (gtk_image_get_type ());
|
|
||||||
|
|
||||||
widget_class = GTK_WIDGET_CLASS (klass);
|
|
||||||
|
|
||||||
widget_class->draw = meta_select_image_draw;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
meta_select_image_draw (GtkWidget *widget,
|
|
||||||
cairo_t *cr)
|
|
||||||
{
|
|
||||||
GtkAllocation allocation;
|
|
||||||
|
|
||||||
gtk_widget_get_allocation (widget, &allocation);
|
|
||||||
|
|
||||||
if (META_SELECT_IMAGE (widget)->selected)
|
|
||||||
{
|
|
||||||
GtkMisc *misc;
|
|
||||||
GtkRequisition requisition;
|
|
||||||
GtkStyleContext *context;
|
|
||||||
GdkRGBA color;
|
|
||||||
int x, y, w, h;
|
|
||||||
gint xpad, ypad;
|
|
||||||
gfloat xalign, yalign;
|
|
||||||
|
|
||||||
misc = GTK_MISC (widget);
|
|
||||||
|
|
||||||
gtk_widget_get_requisition (widget, &requisition);
|
|
||||||
gtk_misc_get_alignment (misc, &xalign, &yalign);
|
|
||||||
gtk_misc_get_padding (misc, &xpad, &ypad);
|
|
||||||
|
|
||||||
x = (allocation.width - (requisition.width - xpad * 2)) * xalign + 0.5;
|
|
||||||
y = (allocation.height - (requisition.height - ypad * 2)) * yalign + 0.5;
|
|
||||||
|
|
||||||
x -= INSIDE_SELECT_RECT + 1;
|
|
||||||
y -= INSIDE_SELECT_RECT + 1;
|
|
||||||
|
|
||||||
w = requisition.width - OUTSIDE_SELECT_RECT * 2 - 1;
|
|
||||||
h = requisition.height - OUTSIDE_SELECT_RECT * 2 - 1;
|
|
||||||
|
|
||||||
context = gtk_widget_get_style_context (widget);
|
|
||||||
|
|
||||||
gtk_style_context_set_state (context,
|
|
||||||
gtk_widget_get_state_flags (widget));
|
|
||||||
|
|
||||||
gtk_style_context_lookup_color (context, "color", &color);
|
|
||||||
|
|
||||||
cairo_set_line_width (cr, 2.0);
|
|
||||||
cairo_set_source_rgb (cr, color.red, color.green, color.blue);
|
|
||||||
|
|
||||||
cairo_rectangle (cr, x, y, w + 1, h + 1);
|
|
||||||
cairo_stroke (cr);
|
|
||||||
|
|
||||||
cairo_set_line_width (cr, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GTK_WIDGET_CLASS (parent_class)->draw (widget, cr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define META_TYPE_SELECT_WORKSPACE (meta_select_workspace_get_type ())
|
|
||||||
#define META_SELECT_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SELECT_WORKSPACE, MetaSelectWorkspace))
|
|
||||||
|
|
||||||
typedef struct _MetaSelectWorkspace MetaSelectWorkspace;
|
|
||||||
typedef struct _MetaSelectWorkspaceClass MetaSelectWorkspaceClass;
|
|
||||||
|
|
||||||
struct _MetaSelectWorkspace
|
|
||||||
{
|
|
||||||
GtkDrawingArea parent_instance;
|
|
||||||
MetaWorkspace *workspace;
|
|
||||||
guint selected : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _MetaSelectWorkspaceClass
|
|
||||||
{
|
|
||||||
GtkDrawingAreaClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static GType meta_select_workspace_get_type (void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
#define SELECT_OUTLINE_WIDTH 2
|
|
||||||
#define MINI_WORKSPACE_WIDTH 48
|
|
||||||
|
|
||||||
static GtkWidget*
|
|
||||||
selectable_workspace_new (MetaWorkspace *workspace)
|
|
||||||
{
|
|
||||||
GtkWidget *widget;
|
|
||||||
double screen_aspect;
|
|
||||||
|
|
||||||
widget = g_object_new (meta_select_workspace_get_type (), NULL);
|
|
||||||
|
|
||||||
screen_aspect = (double) workspace->screen->rect.height /
|
|
||||||
(double) workspace->screen->rect.width;
|
|
||||||
|
|
||||||
/* account for select rect */
|
|
||||||
gtk_widget_set_size_request (widget,
|
|
||||||
MINI_WORKSPACE_WIDTH + SELECT_OUTLINE_WIDTH * 2,
|
|
||||||
MINI_WORKSPACE_WIDTH * screen_aspect + SELECT_OUTLINE_WIDTH * 2);
|
|
||||||
|
|
||||||
META_SELECT_WORKSPACE (widget)->workspace = workspace;
|
|
||||||
|
|
||||||
return widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
select_workspace (GtkWidget *widget)
|
|
||||||
{
|
|
||||||
META_SELECT_WORKSPACE(widget)->selected = TRUE;
|
|
||||||
gtk_widget_queue_draw (widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
unselect_workspace (GtkWidget *widget)
|
|
||||||
{
|
|
||||||
META_SELECT_WORKSPACE (widget)->selected = FALSE;
|
|
||||||
gtk_widget_queue_draw (widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass);
|
|
||||||
|
|
||||||
static gboolean meta_select_workspace_draw (GtkWidget *widget,
|
|
||||||
cairo_t *cr);
|
|
||||||
|
|
||||||
GType
|
|
||||||
meta_select_workspace_get_type (void)
|
|
||||||
{
|
|
||||||
static GType workspace_type = 0;
|
|
||||||
|
|
||||||
if (!workspace_type)
|
|
||||||
{
|
|
||||||
static const GTypeInfo workspace_info =
|
|
||||||
{
|
|
||||||
sizeof (MetaSelectWorkspaceClass),
|
|
||||||
NULL, /* base_init */
|
|
||||||
NULL, /* base_finalize */
|
|
||||||
(GClassInitFunc) meta_select_workspace_class_init,
|
|
||||||
NULL, /* class_finalize */
|
|
||||||
NULL, /* class_data */
|
|
||||||
sizeof (MetaSelectWorkspace),
|
|
||||||
16, /* n_preallocs */
|
|
||||||
(GInstanceInitFunc) NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
workspace_type = g_type_register_static (GTK_TYPE_DRAWING_AREA,
|
|
||||||
"MetaSelectWorkspace",
|
|
||||||
&workspace_info,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return workspace_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass)
|
|
||||||
{
|
|
||||||
GtkWidgetClass *widget_class;
|
|
||||||
|
|
||||||
widget_class = GTK_WIDGET_CLASS (klass);
|
|
||||||
|
|
||||||
widget_class->draw = meta_select_workspace_draw;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* meta_convert_meta_to_wnck:
|
|
||||||
* @window: the #MetaWindow
|
|
||||||
* @screen: the #MetaScreen the window is on
|
|
||||||
*
|
|
||||||
* Converts a #MetaWindow to a #WnckWindowDisplayInfo window
|
|
||||||
* that is used to build a thumbnail of a workspace.
|
|
||||||
**/
|
|
||||||
static WnckWindowDisplayInfo
|
|
||||||
meta_convert_meta_to_wnck (MetaWindow *window, MetaScreen *screen)
|
|
||||||
{
|
|
||||||
WnckWindowDisplayInfo wnck_window;
|
|
||||||
wnck_window.icon = window->icon;
|
|
||||||
wnck_window.mini_icon = window->mini_icon;
|
|
||||||
wnck_window.is_active = window->has_focus;
|
|
||||||
|
|
||||||
if (window->frame)
|
|
||||||
{
|
|
||||||
wnck_window.x = window->frame->rect.x;
|
|
||||||
wnck_window.y = window->frame->rect.y;
|
|
||||||
wnck_window.width = window->frame->rect.width;
|
|
||||||
wnck_window.height = window->frame->rect.height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wnck_window.x = window->rect.x;
|
|
||||||
wnck_window.y = window->rect.y;
|
|
||||||
wnck_window.width = window->rect.width;
|
|
||||||
wnck_window.height = window->rect.height;
|
|
||||||
}
|
|
||||||
return wnck_window;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
meta_select_workspace_draw (GtkWidget *widget,
|
|
||||||
cairo_t *cr)
|
|
||||||
{
|
|
||||||
MetaWorkspace *workspace;
|
|
||||||
WnckWindowDisplayInfo *windows;
|
|
||||||
GtkAllocation allocation;
|
|
||||||
int i, n_windows;
|
|
||||||
GList *tmp, *list;
|
|
||||||
|
|
||||||
workspace = META_SELECT_WORKSPACE (widget)->workspace;
|
|
||||||
|
|
||||||
list = meta_stack_list_windows (workspace->screen->stack, workspace);
|
|
||||||
n_windows = g_list_length (list);
|
|
||||||
windows = g_new (WnckWindowDisplayInfo, n_windows);
|
|
||||||
|
|
||||||
tmp = list;
|
|
||||||
i = 0;
|
|
||||||
while (tmp != NULL)
|
|
||||||
{
|
|
||||||
MetaWindow *window;
|
|
||||||
gboolean ignoreable_sticky;
|
|
||||||
|
|
||||||
window = tmp->data;
|
|
||||||
|
|
||||||
ignoreable_sticky = window->on_all_workspaces &&
|
|
||||||
workspace != workspace->screen->active_workspace;
|
|
||||||
|
|
||||||
if (window->skip_pager ||
|
|
||||||
!meta_window_showing_on_its_workspace (window) ||
|
|
||||||
window->unmaps_pending ||
|
|
||||||
ignoreable_sticky)
|
|
||||||
{
|
|
||||||
--n_windows;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
windows[i] = meta_convert_meta_to_wnck (window, workspace->screen);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_list_free (list);
|
|
||||||
|
|
||||||
gtk_widget_get_allocation (widget, &allocation);
|
|
||||||
|
|
||||||
wnck_draw_workspace (widget,
|
|
||||||
cr,
|
|
||||||
SELECT_OUTLINE_WIDTH,
|
|
||||||
SELECT_OUTLINE_WIDTH,
|
|
||||||
allocation.width - SELECT_OUTLINE_WIDTH * 2,
|
|
||||||
allocation.height - SELECT_OUTLINE_WIDTH * 2,
|
|
||||||
workspace->screen->rect.width,
|
|
||||||
workspace->screen->rect.height,
|
|
||||||
NULL,
|
|
||||||
(workspace->screen->active_workspace == workspace),
|
|
||||||
windows,
|
|
||||||
n_windows);
|
|
||||||
|
|
||||||
g_free (windows);
|
|
||||||
|
|
||||||
if (META_SELECT_WORKSPACE (widget)->selected)
|
|
||||||
{
|
|
||||||
GtkStyleContext *context;
|
|
||||||
GdkRGBA color;
|
|
||||||
|
|
||||||
context = gtk_widget_get_style_context (widget);
|
|
||||||
|
|
||||||
gtk_style_context_set_state (context,
|
|
||||||
gtk_widget_get_state_flags (widget));
|
|
||||||
|
|
||||||
gtk_style_context_lookup_color (context, "color", &color);
|
|
||||||
|
|
||||||
cairo_set_line_width (cr, SELECT_OUTLINE_WIDTH);
|
|
||||||
cairo_set_source_rgb (cr, color.red, color.green, color.blue);
|
|
||||||
|
|
||||||
cairo_rectangle (cr,
|
|
||||||
SELECT_OUTLINE_WIDTH / 2.0, SELECT_OUTLINE_WIDTH / 2.0,
|
|
||||||
allocation.width - SELECT_OUTLINE_WIDTH,
|
|
||||||
allocation.height - SELECT_OUTLINE_WIDTH);
|
|
||||||
cairo_stroke (cr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
@@ -1,65 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
|
|
||||||
/* Mutter tab popup window */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2001 Havoc Pennington
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef META_TABPOPUP_H
|
|
||||||
#define META_TABPOPUP_H
|
|
||||||
|
|
||||||
/* Don't include gtk.h or gdk.h here */
|
|
||||||
#include <meta/common.h>
|
|
||||||
#include <meta/boxes.h>
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <glib.h>
|
|
||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
|
||||||
|
|
||||||
typedef struct _MetaTabEntry MetaTabEntry;
|
|
||||||
typedef struct _MetaTabPopup MetaTabPopup;
|
|
||||||
typedef void *MetaTabEntryKey;
|
|
||||||
|
|
||||||
struct _MetaTabEntry
|
|
||||||
{
|
|
||||||
MetaTabEntryKey key;
|
|
||||||
const char *title;
|
|
||||||
GdkPixbuf *icon;
|
|
||||||
MetaRectangle rect;
|
|
||||||
MetaRectangle inner_rect;
|
|
||||||
guint blank : 1;
|
|
||||||
guint hidden : 1;
|
|
||||||
guint demands_attention : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
MetaTabPopup* meta_ui_tab_popup_new (const MetaTabEntry *entries,
|
|
||||||
int screen_number,
|
|
||||||
int entry_count,
|
|
||||||
int width,
|
|
||||||
gboolean outline);
|
|
||||||
void meta_ui_tab_popup_free (MetaTabPopup *popup);
|
|
||||||
void meta_ui_tab_popup_set_showing (MetaTabPopup *popup,
|
|
||||||
gboolean showing);
|
|
||||||
void meta_ui_tab_popup_forward (MetaTabPopup *popup);
|
|
||||||
void meta_ui_tab_popup_backward (MetaTabPopup *popup);
|
|
||||||
MetaTabEntryKey meta_ui_tab_popup_get_selected (MetaTabPopup *popup);
|
|
||||||
void meta_ui_tab_popup_select (MetaTabPopup *popup,
|
|
||||||
MetaTabEntryKey key);
|
|
||||||
|
|
||||||
|
|
||||||
#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
444
src/ui/ui.c
444
src/ui/ui.c
@@ -22,11 +22,8 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <meta/prefs.h>
|
#include <meta/prefs.h>
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "frames.h"
|
|
||||||
#include <meta/util.h>
|
#include <meta/util.h>
|
||||||
#include "menu.h"
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "theme-private.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -41,7 +38,6 @@ struct _MetaUI
|
|||||||
{
|
{
|
||||||
Display *xdisplay;
|
Display *xdisplay;
|
||||||
Screen *xscreen;
|
Screen *xscreen;
|
||||||
MetaFrames *frames;
|
|
||||||
|
|
||||||
/* For double-click tracking */
|
/* For double-click tracking */
|
||||||
gint button_click_number;
|
gint button_click_number;
|
||||||
@@ -56,11 +52,6 @@ meta_ui_init (void)
|
|||||||
{
|
{
|
||||||
if (!gtk_init_check (NULL, NULL))
|
if (!gtk_init_check (NULL, NULL))
|
||||||
meta_fatal ("Unable to open X display %s\n", XDisplayName (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*
|
Display*
|
||||||
@@ -75,162 +66,6 @@ meta_ui_get_screen_number (void)
|
|||||||
return gdk_screen_get_number (gdk_screen_get_default ());
|
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;
|
typedef struct _EventFunc EventFunc;
|
||||||
|
|
||||||
struct _EventFunc
|
struct _EventFunc
|
||||||
@@ -248,8 +83,7 @@ filter_func (GdkXEvent *xevent,
|
|||||||
{
|
{
|
||||||
g_return_val_if_fail (ef != NULL, GDK_FILTER_CONTINUE);
|
g_return_val_if_fail (ef != NULL, GDK_FILTER_CONTINUE);
|
||||||
|
|
||||||
if ((* ef->func) (xevent, ef->data) ||
|
if ((* ef->func) (xevent, ef->data))
|
||||||
maybe_redirect_mouse_event (xevent))
|
|
||||||
return GDK_FILTER_REMOVE;
|
return GDK_FILTER_REMOVE;
|
||||||
else
|
else
|
||||||
return GDK_FILTER_CONTINUE;
|
return GDK_FILTER_CONTINUE;
|
||||||
@@ -297,12 +131,6 @@ meta_ui_new (Display *xdisplay,
|
|||||||
gdisplay = gdk_x11_lookup_xdisplay (xdisplay);
|
gdisplay = gdk_x11_lookup_xdisplay (xdisplay);
|
||||||
g_assert (gdisplay == gdk_display_get_default ());
|
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);
|
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui);
|
||||||
|
|
||||||
return ui;
|
return ui;
|
||||||
@@ -313,33 +141,12 @@ meta_ui_free (MetaUI *ui)
|
|||||||
{
|
{
|
||||||
GdkDisplay *gdisplay;
|
GdkDisplay *gdisplay;
|
||||||
|
|
||||||
gtk_widget_destroy (GTK_WIDGET (ui->frames));
|
|
||||||
|
|
||||||
gdisplay = gdk_x11_lookup_xdisplay (ui->xdisplay);
|
gdisplay = gdk_x11_lookup_xdisplay (ui->xdisplay);
|
||||||
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", NULL);
|
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", NULL);
|
||||||
|
|
||||||
g_free (ui);
|
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
|
Window
|
||||||
meta_ui_create_frame_window (MetaUI *ui,
|
meta_ui_create_frame_window (MetaUI *ui,
|
||||||
Display *xdisplay,
|
Display *xdisplay,
|
||||||
@@ -351,72 +158,13 @@ meta_ui_create_frame_window (MetaUI *ui,
|
|||||||
gint screen_no,
|
gint screen_no,
|
||||||
gulong *create_serial)
|
gulong *create_serial)
|
||||||
{
|
{
|
||||||
GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
|
return None;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_ui_destroy_frame_window (MetaUI *ui,
|
meta_ui_destroy_frame_window (MetaUI *ui,
|
||||||
Window xwindow)
|
Window xwindow)
|
||||||
{
|
{
|
||||||
meta_frames_unmanage_window (ui->frames, xwindow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -427,83 +175,6 @@ meta_ui_move_resize_frame (MetaUI *ui,
|
|||||||
int width,
|
int width,
|
||||||
int height)
|
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
|
void
|
||||||
@@ -511,41 +182,12 @@ meta_ui_set_frame_title (MetaUI *ui,
|
|||||||
Window xwindow,
|
Window xwindow,
|
||||||
const char *title)
|
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
|
void
|
||||||
meta_ui_window_menu_popup (MetaWindowMenu *menu,
|
meta_ui_update_frame_style (MetaUI *ui,
|
||||||
int root_x,
|
Window xwindow)
|
||||||
int root_y,
|
|
||||||
int button,
|
|
||||||
guint32 timestamp)
|
|
||||||
{
|
{
|
||||||
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*
|
GdkPixbuf*
|
||||||
@@ -724,66 +366,10 @@ meta_ui_theme_get_frame_borders (MetaUI *ui,
|
|||||||
MetaFrameType type,
|
MetaFrameType type,
|
||||||
MetaFrameFlags flags,
|
MetaFrameFlags flags,
|
||||||
MetaFrameBorders *borders)
|
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);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_ui_accelerator_parse (const char *accel,
|
meta_ui_accelerator_parse (const char *accel,
|
||||||
guint *keysym,
|
guint *keysym,
|
||||||
@@ -974,33 +560,13 @@ meta_ui_parse_modifier (const char *accel,
|
|||||||
return TRUE;
|
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
|
int
|
||||||
meta_ui_get_drag_threshold (MetaUI *ui)
|
meta_ui_get_drag_threshold (MetaUI *ui)
|
||||||
{
|
{
|
||||||
GtkSettings *settings;
|
GtkSettings *settings;
|
||||||
int threshold;
|
int threshold;
|
||||||
|
|
||||||
settings = gtk_widget_get_settings (GTK_WIDGET (ui->frames));
|
settings = gtk_settings_get_default ();
|
||||||
|
|
||||||
threshold = 8;
|
threshold = 8;
|
||||||
g_object_get (G_OBJECT (settings), "gtk-dnd-drag-threshold", &threshold, NULL);
|
g_object_get (G_OBJECT (settings), "gtk-dnd-drag-threshold", &threshold, NULL);
|
||||||
|
59
src/ui/ui.h
59
src/ui/ui.h
@@ -61,16 +61,6 @@ void meta_ui_theme_get_frame_borders (MetaUI *ui,
|
|||||||
MetaFrameType type,
|
MetaFrameType type,
|
||||||
MetaFrameFlags flags,
|
MetaFrameFlags flags,
|
||||||
MetaFrameBorders *borders);
|
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,
|
Window meta_ui_create_frame_window (MetaUI *ui,
|
||||||
Display *xdisplay,
|
Display *xdisplay,
|
||||||
Visual *xvisual,
|
Visual *xvisual,
|
||||||
@@ -88,54 +78,12 @@ void meta_ui_move_resize_frame (MetaUI *ui,
|
|||||||
int y,
|
int y,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
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,
|
void meta_ui_set_frame_title (MetaUI *ui,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
const char *title);
|
const char *title);
|
||||||
|
|
||||||
void meta_ui_update_frame_style (MetaUI *ui,
|
void meta_ui_update_frame_style (MetaUI *ui,
|
||||||
Window window);
|
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 */
|
/* FIXME these lack a display arg */
|
||||||
GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
|
GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
|
||||||
int src_x,
|
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,
|
char* meta_text_property_to_utf8 (Display *xdisplay,
|
||||||
const XTextProperty *prop);
|
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
|
/* Not a real key symbol but means "key above the tab key"; this is
|
||||||
* used as the default keybinding for cycle_group.
|
* used as the default keybinding for cycle_group.
|
||||||
* 0x2xxxxxxx is a range not used by GDK or X. the remaining digits are
|
* 0x2xxxxxxx is a range not used by GDK or X. the remaining digits are
|
||||||
@@ -171,13 +116,9 @@ gboolean meta_ui_parse_modifier (const char *accel,
|
|||||||
/* Caller responsible for freeing return string of meta_ui_accelerator_name! */
|
/* Caller responsible for freeing return string of meta_ui_accelerator_name! */
|
||||||
gchar* meta_ui_accelerator_name (unsigned int keysym,
|
gchar* meta_ui_accelerator_name (unsigned int keysym,
|
||||||
MetaVirtualModifier mask);
|
MetaVirtualModifier mask);
|
||||||
gboolean meta_ui_window_is_widget (MetaUI *ui,
|
|
||||||
Window xwindow);
|
|
||||||
|
|
||||||
int meta_ui_get_drag_threshold (MetaUI *ui);
|
int meta_ui_get_drag_threshold (MetaUI *ui);
|
||||||
|
|
||||||
MetaUIDirection meta_ui_get_direction (void);
|
MetaUIDirection meta_ui_get_direction (void);
|
||||||
|
|
||||||
#include "tabpopup.h"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user