diff options
27 files changed, 2142 insertions, 854 deletions
diff --git a/cmake/CompizPlugin.cmake b/cmake/CompizPlugin.cmake index 10a4a6f..c9bbf70 100644 --- a/cmake/CompizPlugin.cmake +++ b/cmake/CompizPlugin.cmake @@ -108,9 +108,9 @@ macro (_prepare_directories) set (PLUGIN_PKGDIR ${libdir}/pkgconfig) set (PLUGIN_XMLDIR ${datadir}/compiz) - if (NOT "${CMAKE_BUILD_TYPE}") + if (NOT CMAKE_BUILD_TYPE) set (CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Build type (Debug/Release/RelWithDebInfo/MinSizeRe)" FORCE) - endif (NOT "${CMAKE_BUILD_TYPE}") + endif (NOT CMAKE_BUILD_TYPE) elseif ("${COMPIZ_PLUGIN_INSTALL_TYPE}" STREQUAL "compiz" OR "$ENV{BUILD_GLOBAL}" STREQUAL "true") set (PLUGIN_BUILDTYPE global) @@ -120,9 +120,9 @@ macro (_prepare_directories) set (PLUGIN_PKGDIR ${COMPIZ_LIBDIR}/pkgconfig) set (PLUGIN_XMLDIR ${COMPIZ_PREFIX}/share/compiz) - if (NOT "${CMAKE_BUILD_TYPE}") + if (NOT CMAKE_BUILD_TYPE) set (CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type (Debug/Release/RelWithDebInfo/MinSizeRe)" FORCE) - endif (NOT "${CMAKE_BUILD_TYPE}") + endif (NOT CMAKE_BUILD_TYPE) else ("${COMPIZ_PLUGIN_INSTALL_TYPE}" STREQUAL "compiz" OR "$ENV{BUILD_GLOBAL}" STREQUAL "true") set (PLUGIN_BUILDTYPE local) @@ -130,9 +130,9 @@ macro (_prepare_directories) set (PLUGIN_LIBDIR $ENV{HOME}/.compiz-1/plugins) set (PLUGIN_XMLDIR $ENV{HOME}/.compiz-1/metadata) - if (NOT "${CMAKE_BUILD_TYPE}") + if (NOT CMAKE_BUILD_TYPE) set (CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type (Debug/Release/RelWithDebInfo/MinSizeRe)" FORCE) - endif (NOT "${CMAKE_BUILD_TYPE}") + endif (NOT CMAKE_BUILD_TYPE) endif ("${COMPIZ_PLUGIN_INSTALL_TYPE}" STREQUAL "package") endmacro (_prepare_directories) diff --git a/gtk/window-decorator/CMakeLists.txt b/gtk/window-decorator/CMakeLists.txt index 9cd5c96..3cb61a6 100644 --- a/gtk/window-decorator/CMakeLists.txt +++ b/gtk/window-decorator/CMakeLists.txt @@ -37,6 +37,7 @@ if (USE_GTK) blurprops.c decorprops.c cairo.c + frames.c gdk.c switcher.c metacity.c diff --git a/gtk/window-decorator/TODO b/gtk/window-decorator/TODO index d1b8e93..f45fd8a 100644 --- a/gtk/window-decorator/TODO +++ b/gtk/window-decorator/TODO @@ -3,4 +3,16 @@ * Plugin with SVG-based theme support -* Plugin that supports old metacity themes
\ No newline at end of file +* Plugin that supports old metacity themes + +----- Cleanup TODO: + * Allow frame keying types for frame types, so + /2d/window_type/state/id , this way we can have + different shadows per-frame and much more granular + memory control (decor_t just becomes a handle to some + decoration specific stuff, decor_frame_t becomes a + table of shared resources held by all decor_t's + * Completely seal off the values of structs and use + only getter and setter functions to control API + * Start implementing a system in GObject + * Put all the globals into their own structs or namespaces diff --git a/gtk/window-decorator/actionmenu.c b/gtk/window-decorator/actionmenu.c index 27c9821..f1549aa 100644 --- a/gtk/window-decorator/actionmenu.c +++ b/gtk/window-decorator/actionmenu.c @@ -1,3 +1,24 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + */ + #include "gtk-window-decorator.h" static void @@ -14,6 +35,8 @@ position_action_menu (GtkMenu *menu, gpointer user_data) { WnckWindow *win = (WnckWindow *) user_data; + WnckWindowType win_type = wnck_window_get_window_type (win); + decor_frame_t *frame = gwd_get_decor_frame (get_frame_type (win_type)); decor_t *d = g_object_get_data (G_OBJECT (win), "decor"); gint bx, by, width, height; @@ -21,7 +44,9 @@ position_action_menu (GtkMenu *menu, if ((*theme_get_button_position) (d, BUTTON_MENU, width, height, &bx, &by, &width, &height)) - *x = *x - _win_extents.left + bx; + *x = *x - frame->win_extents.left + bx; + + gwd_decor_frame_unref (frame); if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL) { diff --git a/gtk/window-decorator/blurprops.c b/gtk/window-decorator/blurprops.c index d30979b..84972ed 100644 --- a/gtk/window-decorator/blurprops.c +++ b/gtk/window-decorator/blurprops.c @@ -1,3 +1,24 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + */ + #include "gtk-window-decorator.h" void @@ -17,13 +38,13 @@ decor_update_blur_property (decor_t *d, long *data = NULL; int size = 0; - if (blur_type != BLUR_TYPE_ALL) + if (settings->blur_type != BLUR_TYPE_ALL) { bottom_region = NULL; left_region = NULL; right_region = NULL; - if (blur_type != BLUR_TYPE_TITLEBAR) + if (settings->blur_type != BLUR_TYPE_TITLEBAR) top_region = NULL; } @@ -65,4 +86,4 @@ decor_update_blur_property (decor_t *d, gdk_display_sync (gdk_display_get_default ()); gdk_error_trap_pop (); } -}
\ No newline at end of file +} diff --git a/gtk/window-decorator/cairo.c b/gtk/window-decorator/cairo.c index a9b8f42..c600cf1 100644 --- a/gtk/window-decorator/cairo.c +++ b/gtk/window-decorator/cairo.c @@ -1,3 +1,28 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + * + * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com> + * Frames Management: Copright © 2011 Canonical Ltd. + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> + */ + #include "gtk-window-decorator.h" void @@ -280,7 +305,8 @@ draw_window_decoration (decor_t *d) if (!d->pixmap) return; - style = gtk_widget_get_style (style_window_rgba); + + style = gtk_widget_get_style (d->frame->style_window_rgba); if (d->state & (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY | WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)) @@ -310,12 +336,12 @@ draw_window_decoration (decor_t *d) cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - top = _win_extents.top + titlebar_height; + top = d->frame->win_extents.top + d->frame->titlebar_height; - x1 = d->context->left_space - _win_extents.left; - y1 = d->context->top_space - _win_extents.top - titlebar_height; - x2 = d->width - d->context->right_space + _win_extents.right; - y2 = d->height - d->context->bottom_space + _win_extents.bottom; + x1 = d->context->left_space - d->frame->win_extents.left; + y1 = d->context->top_space - d->frame->win_extents.top - d->frame->titlebar_height; + x2 = d->width - d->context->right_space + d->frame->win_extents.right; + y2 = d->height - d->context->bottom_space + d->frame->win_extents.bottom; h = d->height - d->context->top_space - d->context->bottom_space; @@ -328,31 +354,31 @@ draw_window_decoration (decor_t *d) { decor_color_t *title_color = _title_color; - alpha = decoration_alpha + 0.3; + alpha = settings->decoration_alpha + 0.3; fill_rounded_rectangle (cr, x1 + 0.5, y1 + 0.5, - _win_extents.left - 0.5, + d->frame->win_extents.left - 0.5, top - 0.5, 5.0, CORNER_TOPLEFT & corners, &title_color[0], 1.0, &title_color[1], alpha, SHADE_TOP | SHADE_LEFT); fill_rounded_rectangle (cr, - x1 + _win_extents.left, + x1 + d->frame->win_extents.left, y1 + 0.5, - x2 - x1 - _win_extents.left - - _win_extents.right, + x2 - x1 - d->frame->win_extents.left - + d->frame->win_extents.right, top - 0.5, 5.0, 0, &title_color[0], 1.0, &title_color[1], alpha, SHADE_TOP); fill_rounded_rectangle (cr, - x2 - _win_extents.right, + x2 - d->frame->win_extents.right, y1 + 0.5, - _win_extents.right - 0.5, + d->frame->win_extents.right - 0.5, top - 0.5, 5.0, CORNER_TOPRIGHT & corners, &title_color[0], 1.0, &title_color[1], alpha, @@ -360,31 +386,31 @@ draw_window_decoration (decor_t *d) } else { - alpha = decoration_alpha; + alpha = settings->decoration_alpha; fill_rounded_rectangle (cr, x1 + 0.5, y1 + 0.5, - _win_extents.left - 0.5, + d->frame->win_extents.left - 0.5, top - 0.5, 5.0, CORNER_TOPLEFT & corners, &color, 1.0, &color, alpha, SHADE_TOP | SHADE_LEFT); fill_rounded_rectangle (cr, - x1 + _win_extents.left, + x1 + d->frame->win_extents.left, y1 + 0.5, - x2 - x1 - _win_extents.left - - _win_extents.right, + x2 - x1 - d->frame->win_extents.left - + d->frame->win_extents.right, top - 0.5, 5.0, 0, &color, 1.0, &color, alpha, SHADE_TOP); fill_rounded_rectangle (cr, - x2 - _win_extents.right, + x2 - d->frame->win_extents.right, y1 + 0.5, - _win_extents.right - 0.5, + d->frame->win_extents.right - 0.5, top - 0.5, 5.0, CORNER_TOPRIGHT & corners, &color, 1.0, &color, alpha, @@ -394,16 +420,16 @@ draw_window_decoration (decor_t *d) fill_rounded_rectangle (cr, x1 + 0.5, y1 + top, - _win_extents.left - 0.5, + d->frame->win_extents.left - 0.5, h, 5.0, 0, &color, 1.0, &color, alpha, SHADE_LEFT); fill_rounded_rectangle (cr, - x2 - _win_extents.right, + x2 - d->frame->win_extents.right, y1 + top, - _win_extents.right - 0.5, + d->frame->win_extents.right - 0.5, h, 5.0, 0, &color, 1.0, &color, alpha, @@ -412,28 +438,28 @@ draw_window_decoration (decor_t *d) fill_rounded_rectangle (cr, x1 + 0.5, - y2 - _win_extents.bottom, - _win_extents.left - 0.5, - _win_extents.bottom - 0.5, + y2 - d->frame->win_extents.bottom, + d->frame->win_extents.left - 0.5, + d->frame->win_extents.bottom - 0.5, 5.0, CORNER_BOTTOMLEFT & corners, &color, 1.0, &color, alpha, SHADE_BOTTOM | SHADE_LEFT); fill_rounded_rectangle (cr, - x1 + _win_extents.left, - y2 - _win_extents.bottom, - x2 - x1 - _win_extents.left - - _win_extents.right, - _win_extents.bottom - 0.5, + x1 + d->frame->win_extents.left, + y2 - d->frame->win_extents.bottom, + x2 - x1 - d->frame->win_extents.left - + d->frame->win_extents.right, + d->frame->win_extents.bottom - 0.5, 5.0, 0, &color, 1.0, &color, alpha, SHADE_BOTTOM); fill_rounded_rectangle (cr, - x2 - _win_extents.right, - y2 - _win_extents.bottom, - _win_extents.right - 0.5, - _win_extents.bottom - 0.5, + x2 - d->frame->win_extents.right, + y2 - d->frame->win_extents.bottom, + d->frame->win_extents.right - 0.5, + d->frame->win_extents.bottom - 0.5, 5.0, CORNER_BOTTOMRIGHT & corners, &color, 1.0, &color, alpha, SHADE_BOTTOM | SHADE_RIGHT); @@ -520,7 +546,7 @@ draw_window_decoration (decor_t *d) if (d->actions & WNCK_WINDOW_ACTION_CLOSE) { button_state_offsets (button_x, - y1 - 3.0 + titlebar_height / 2, + y1 - 3.0 + d->frame->titlebar_height / 2, d->button_states[BUTTON_CLOSE], &x, &y); button_x -= 17; @@ -547,7 +573,7 @@ draw_window_decoration (decor_t *d) if (d->actions & WNCK_WINDOW_ACTION_MAXIMIZE) { button_state_offsets (button_x, - y1 - 3.0 + titlebar_height / 2, + y1 - 3.0 + d->frame->titlebar_height / 2, d->button_states[BUTTON_MAX], &x, &y); button_x -= 17; @@ -592,7 +618,7 @@ draw_window_decoration (decor_t *d) if (d->actions & WNCK_WINDOW_ACTION_MINIMIZE) { button_state_offsets (button_x, - y1 - 3.0 + titlebar_height / 2, + y1 - 3.0 + d->frame->titlebar_height / 2, d->button_states[BUTTON_MIN], &x, &y); button_x -= 17; @@ -627,7 +653,7 @@ draw_window_decoration (decor_t *d) { cairo_move_to (cr, d->context->left_space + 21.0, - y1 + 2.0 + (titlebar_height - text_height) / 2.0); + y1 + 2.0 + (d->frame->titlebar_height - d->frame->text_height) / 2.0); gdk_cairo_set_source_color_alpha (cr, &style->fg[GTK_STATE_NORMAL], @@ -647,7 +673,7 @@ draw_window_decoration (decor_t *d) cairo_move_to (cr, d->context->left_space + 21.0, - y1 + 2.0 + (titlebar_height - text_height) / 2.0); + y1 + 2.0 + (d->frame->titlebar_height - d->frame->text_height) / 2.0); pango_cairo_show_layout (cr, d->layout); } @@ -655,7 +681,7 @@ draw_window_decoration (decor_t *d) if (d->icon) { cairo_translate (cr, d->context->left_space + 1, - y1 - 5.0 + titlebar_height / 2); + y1 - 5.0 + d->frame->titlebar_height / 2); cairo_set_source (cr, d->icon); cairo_rectangle (cr, 0.0, 0.0, 16.0, 16.0); cairo_clip (cr); @@ -740,7 +766,7 @@ calc_decoration_size (decor_t *d, if (w < top_width) top_width = MAX (ICON_SPACE + d->button_width, w); - decor_get_default_layout (&window_context, top_width, 1, &layout); + decor_get_default_layout (&d->frame->window_context, top_width, 1, &layout); if (!d->context || memcmp (&layout, &d->border_layout, sizeof (layout))) { @@ -748,8 +774,8 @@ calc_decoration_size (decor_t *d, *height = layout.height; d->border_layout = layout; - d->context = &window_context; - d->shadow = border_shadow; + d->context = &d->frame->window_context; + d->shadow = d->frame->border_shadow; return TRUE; } @@ -764,15 +790,15 @@ calc_decoration_size (decor_t *d, if (w < top_width) top_width = MAX (ICON_SPACE + d->button_width, w); - decor_get_default_layout (&window_context_no_shadow, + decor_get_default_layout (&d->frame->window_context_no_shadow, d->client_width, d->client_height, &layout); *width = layout.width; *height = layout.height; d->border_layout = layout; - d->context = &window_context_no_shadow; - d->shadow = border_no_shadow; + d->context = &d->frame->window_context_no_shadow; + d->shadow = d->frame->border_no_shadow; return TRUE; } @@ -795,20 +821,20 @@ get_button_position (decor_t *d, if (d->frame_window) { - *x = bpos[i].x + bpos[i].xw * width + _win_extents.left + 4; + *x = bpos[i].x + bpos[i].xw * width + d->frame->win_extents.left + 4; *y = bpos[i].y + bpos[i].yh * height + bpos[i].yth * - (titlebar_height - 17) + _win_extents.top + 2; + (d->frame->titlebar_height - 17) + d->frame->win_extents.top + 2; } else { *x = bpos[i].x + bpos[i].xw * width; *y = bpos[i].y + bpos[i].yh * height + bpos[i].yth * - (titlebar_height - 17); + (d->frame->titlebar_height - 17); } *w = bpos[i].w + bpos[i].ww * width; *h = bpos[i].h + bpos[i].hh * height + bpos[i].hth + - (titlebar_height - 17); + (d->frame->titlebar_height - 17); /* hack to position multiple buttons on the right */ if (i != BUTTON_MENU) @@ -830,18 +856,18 @@ get_event_window_position (decor_t *d, { if (d->frame_window) { - *x = pos[i][j].x + pos[i][j].xw * width + _win_extents.left; - *y = pos[i][j].y + _win_extents.top + - pos[i][j].yh * height + pos[i][j].yth * (titlebar_height - 17); + *x = pos[i][j].x + pos[i][j].xw * width + d->frame->win_extents.left; + *y = pos[i][j].y + d->frame->win_extents.top + + pos[i][j].yh * height + pos[i][j].yth * (d->frame->titlebar_height - 17); if (i == 0 && (j == 0 || j == 2)) - *y -= titlebar_height; + *y -= d->frame->titlebar_height; } else { *x = pos[i][j].x + pos[i][j].xw * width; *y = pos[i][j].y + - pos[i][j].yh * height + pos[i][j].yth * (titlebar_height - 17); + pos[i][j].yh * height + pos[i][j].yth * (d->frame->titlebar_height - 17); } if ((d->state & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY) && @@ -862,15 +888,28 @@ get_event_window_position (decor_t *d, else { *h = pos[i][j].h + - pos[i][j].hh * height + pos[i][j].hth * (titlebar_height - 17); + pos[i][j].hh * height + pos[i][j].hth * (d->frame->titlebar_height - 17); } } +gfloat +get_title_scale (decor_frame_t *frame) +{ + return 1.0f; +} + void -update_border_extents (gint text_height) +update_border_extents (decor_frame_t *frame) { - _win_extents = _default_win_extents; - _max_win_extents = _default_win_extents; - max_titlebar_height = titlebar_height = - (text_height < 17) ? 17 : text_height; + decor_frame_t *default_frame = gwd_get_decor_frame ("default"); + + frame = gwd_decor_frame_ref (frame); + + frame->win_extents = default_frame->win_extents; + frame->max_win_extents = default_frame->win_extents; + frame->titlebar_height = frame->max_titlebar_height = + (frame->text_height < 17) ? 17 : frame->text_height; + + gwd_decor_frame_unref (frame); + gwd_decor_frame_unref (default_frame); } diff --git a/gtk/window-decorator/decorator.c b/gtk/window-decorator/decorator.c index 17bb8f6..9520759 100644 --- a/gtk/window-decorator/decorator.c +++ b/gtk/window-decorator/decorator.c @@ -1,5 +1,110 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + * + * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com> + * Frames Management: Copright © 2011 Canonical Ltd. + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> + */ + #include "gtk-window-decorator.h" +decor_frame_t * +create_normal_frame (const gchar *type) +{ + decor_frame_t *frame = decor_frame_new (type); + + decor_context_t _window_context = { + { 0, 0, 0, 0 }, + 6, 6, 4, 6, + 0, 0, 0, 0 + }; + + decor_context_t _max_window_context = { + { 0, 0, 0, 0 }, + 6, 6, 4, 6, + 0, 0, 0, 0 + }; + + decor_context_t _window_context_no_shadow = { + { 0, 0, 0, 0 }, + 6, 6, 4, 6, + 0, 0, 0, 0 + }; + + decor_context_t _max_window_context_no_shadow = { + { 0, 0, 0, 0 }, + 6, 6, 4, 6, + 0, 0, 0, 0 + }; + + decor_extents_t _win_extents = { 6, 6, 6, 6 }; + decor_extents_t _max_win_extents = { 6, 6, 4, 6 }; + + frame->win_extents = _win_extents; + frame->max_win_extents = _max_win_extents; + frame->update_shadow = decor_frame_update_shadow; + frame->window_context = _window_context; + frame->window_context_no_shadow = _window_context_no_shadow; + frame->max_window_context = _max_window_context; + frame->max_window_context_no_shadow = _max_window_context_no_shadow; + + return frame; +} + +void +destroy_normal_frame (decor_frame_t *frame) +{ + decor_frame_destroy (frame); +} + +decor_frame_t * +create_bare_frame (const gchar *type) +{ + decor_frame_t *frame = decor_frame_new (type); + decor_context_t _shadow_context = { + { 0, 0, 0, 0 }, + 0, 0, 0, 0, + 0, 0, 0, 0, + }; + + decor_extents_t _shadow_extents = { 0, 0, 0, 0 }; + + frame->win_extents = _shadow_extents; + frame->max_win_extents = _shadow_extents; + frame->win_extents = _shadow_extents; + frame->window_context = _shadow_context; + frame->window_context_no_shadow = _shadow_context; + frame->max_window_context = _shadow_context; + frame->max_window_context_no_shadow = _shadow_context; + frame->update_shadow = bare_frame_update_shadow; + + return frame; +} + +void +destroy_bare_frame (decor_frame_t *frame) +{ + decor_frame_destroy (frame); +} + + /* * get_titlebar_font * @@ -7,31 +112,31 @@ * Description: Helper function to get the font for the titlebar */ static const PangoFontDescription * -get_titlebar_font (void) +get_titlebar_font (decor_frame_t *frame) { - if (use_system_font) - { + if (settings->use_system_font) return NULL; - } else - return titlebar_font; + return frame->titlebar_font; } /* - * update_titlebar_font + * frame_update_titlebar_font * * Returns: void * Description: updates the titlebar font from the pango context, should * be called whenever the gtk style or font has changed */ void -update_titlebar_font (void) +frame_update_titlebar_font (decor_frame_t *frame) { const PangoFontDescription *font_desc; PangoFontMetrics *metrics; PangoLanguage *lang; - font_desc = get_titlebar_font (); + frame = gwd_decor_frame_ref (frame); + + font_desc = get_titlebar_font (frame); if (!font_desc) { GtkStyle *default_style; @@ -40,17 +145,34 @@ update_titlebar_font (void) font_desc = default_style->font_desc; } - pango_context_set_font_description (pango_context, font_desc); + pango_context_set_font_description (frame->pango_context, font_desc); - lang = pango_context_get_language (pango_context); - metrics = pango_context_get_metrics (pango_context, font_desc, lang); + lang = pango_context_get_language (frame->pango_context); + metrics = pango_context_get_metrics (frame->pango_context, font_desc, lang); - text_height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) + + frame->text_height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics)); + gwd_decor_frame_unref (frame); + pango_font_metrics_unref (metrics); } +void +update_frames_titlebar_fonts (gpointer key, + gpointer value, + gpointer user_data) +{ + frame_update_titlebar_font ((decor_frame_t *) value); +} + +void +update_titlebar_font () +{ + gwd_frames_foreach (update_frames_titlebar_fonts, NULL); +} + + /* * update_event_windows * @@ -291,7 +413,7 @@ max_window_name_width (WnckWindow *win) /* Ensure that a layout is created */ if (!d->layout) { - d->layout = pango_layout_new (pango_context); + d->layout = pango_layout_new (d->frame->pango_context); if (!d->layout) return 0; @@ -428,10 +550,10 @@ update_window_decoration_icon (WnckWindow *win) /* 32 bit pixmap on pixmap mode, 24 for reparenting */ if (d->frame_window) d->icon_pixmap = pixmap_new_from_pixbuf (d->icon_pixbuf, - 24); + d->frame->style_window_rgba); else d->icon_pixmap = pixmap_new_from_pixbuf (d->icon_pixbuf, - 32); + d->frame->style_window_rgb); cr = gdk_cairo_create (GDK_DRAWABLE (d->icon_pixmap)); d->icon = cairo_pattern_create_for_surface (cairo_get_target (cr)); cairo_destroy (cr); @@ -459,7 +581,6 @@ update_window_decoration_size (WnckWindow *win) gint x, y, w, h, name_width; Display *xdisplay; XRenderPictFormat *format; - int depth; xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); @@ -482,12 +603,9 @@ update_window_decoration_size (WnckWindow *win) /* Get the correct depth for the frame window in reparenting mode, otherwise * enforce 32 */ if (d->frame_window) - depth = gdk_drawable_get_depth (GDK_DRAWABLE (d->frame_window)); + pixmap = create_pixmap (width, height, d->frame->style_window_rgb); else - depth = 32; - - /* Create pixmap of decoration size */ - pixmap = create_pixmap (width, height, depth); + pixmap = create_pixmap (width, height, d->frame->style_window_rgba); gdk_flush (); @@ -500,8 +618,10 @@ update_window_decoration_size (WnckWindow *win) gdk_error_trap_push (); - /* Create backbuffer pixmap */ - buffer_pixmap = create_pixmap (width, height, depth); + if (d->frame_window) + buffer_pixmap = create_pixmap (width, height, d->frame->style_window_rgb); + else + buffer_pixmap = create_pixmap (width, height, d->frame->style_window_rgba); gdk_flush (); @@ -571,10 +691,16 @@ draw_border_shape (Display *xdisplay, static XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; GdkColormap *colormap; decor_t d; + decor_shadow_info_t *info = (decor_shadow_info_t *) closure; double save_decoration_alpha; memset (&d, 0, sizeof (d)); + if (info) + d.frame = info->frame; + else + d.frame = gwd_get_decor_frame ("default"); + d.pixmap = gdk_pixmap_foreign_new_for_display (gdk_display_get_default (), pixmap); d.width = width; @@ -585,23 +711,25 @@ draw_border_shape (Display *xdisplay, d.context = c; /* we use closure argument if maximized */ - if (closure) - d.state |= - WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY | - WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY; + if (info) + d.state = info->state; + else + d.state = 0; decor_get_default_layout (c, 1, 1, &d.border_layout); colormap = get_colormap_for_drawable (GDK_DRAWABLE (d.pixmap)); gdk_drawable_set_colormap (d.pixmap, colormap); - /* create shadow from opaque decoration */ - save_decoration_alpha = decoration_alpha; - decoration_alpha = 1.0; + /* create shadow from opaque decoration + * FIXME: Should not modify settings value + * like this */ + save_decoration_alpha = settings->decoration_alpha; + settings->decoration_alpha = 1.0; (*d.draw) (&d); - decoration_alpha = save_decoration_alpha; + settings->decoration_alpha = save_decoration_alpha; XRenderFillRectangle (xdisplay, PictOpSrc, picture, &white, c->left_space, @@ -609,9 +737,13 @@ draw_border_shape (Display *xdisplay, width - c->left_space - c->right_space, height - c->top_space - c->bottom_space); + if (!info) + gwd_decor_frame_unref (d.frame); + g_object_unref (G_OBJECT (d.pixmap)); } + /* * update_shadow * Returns: 1 for success, 0 for failure @@ -628,183 +760,264 @@ draw_border_shape (Display *xdisplay, * * We do something similar for the maximimzed mode as well */ -int -update_shadow (void) +void +bare_frame_update_shadow (Display *xdisplay, + Screen *screen, + decor_frame_t *frame, + decor_shadow_info_t *info, + decor_shadow_options_t *opt_shadow, + decor_shadow_options_t *opt_no_shadow) { - decor_shadow_options_t opt_shadow; - decor_shadow_options_t opt_no_shadow; - Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - GdkDisplay *display = gdk_display_get_default (); - GdkScreen *screen = gdk_display_get_default_screen (display); - - /* Pixmap mode non maximized window shadow */ - opt_shadow.shadow_radius = shadow_radius; - opt_shadow.shadow_opacity = shadow_opacity; - - memcpy (opt_shadow.shadow_color, shadow_color, sizeof (shadow_color)); - - opt_shadow.shadow_offset_x = shadow_offset_x; - opt_shadow.shadow_offset_y = shadow_offset_y; - - /* Reparenting mode non maximized window shadow */ - opt_no_shadow.shadow_radius = 0; - opt_no_shadow.shadow_opacity = 0; - - opt_no_shadow.shadow_offset_x = 0; - opt_no_shadow.shadow_offset_y = 0; - - /* Create a special no_border_shadow for the pixmap mode in case we need it */ - if (no_border_shadow) + if (frame->border_shadow) { - decor_shadow_destroy (xdisplay, no_border_shadow); - no_border_shadow = NULL; + decor_shadow_destroy (xdisplay, frame->border_shadow); + frame->border_shadow = NULL; } - no_border_shadow = decor_shadow_create (xdisplay, - gdk_x11_screen_get_xscreen (screen), + frame->border_shadow = decor_shadow_create (xdisplay, + screen, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - &opt_shadow, - &shadow_context, + opt_shadow, + &frame->window_context, decor_draw_simple, - 0); + NULL); +} - /* Normal window shadow pixmap mode */ - if (border_shadow) +void +switcher_frame_update_shadow (Display *xdisplay, + Screen *screen, + decor_frame_t *frame, + decor_shadow_info_t *info, + decor_shadow_options_t *opt_shadow, + decor_shadow_options_t *opt_no_shadow) +{ + if (frame->border_shadow) { - decor_shadow_destroy (xdisplay, border_shadow); - border_shadow = NULL; + decor_shadow_destroy (xdisplay, frame->border_shadow); + frame->border_shadow = NULL; } - border_shadow = decor_shadow_create (xdisplay, - gdk_x11_screen_get_xscreen (screen), - 1, 1, - _win_extents.left, - _win_extents.right, - _win_extents.top + titlebar_height, - _win_extents.bottom, - _win_extents.left - - TRANSLUCENT_CORNER_SIZE, - _win_extents.right - - TRANSLUCENT_CORNER_SIZE, - _win_extents.top + titlebar_height - - TRANSLUCENT_CORNER_SIZE, - _win_extents.bottom - - TRANSLUCENT_CORNER_SIZE, - &opt_shadow, - &window_context, - draw_border_shape, - 0); + frame->border_shadow = decor_shadow_create (xdisplay, + screen, + 1, 1, + frame->win_extents.left, + frame->win_extents.right, + frame->win_extents.top, + frame->win_extents.bottom, + frame->win_extents.left - + TRANSLUCENT_CORNER_SIZE, + frame->win_extents.right - + TRANSLUCENT_CORNER_SIZE, + frame->win_extents.top - + TRANSLUCENT_CORNER_SIZE, + frame->win_extents.bottom - + TRANSLUCENT_CORNER_SIZE, + opt_shadow, + &frame->window_context, + decor_draw_simple, + NULL); +} - /* Enforced zero-shadow for reparenting mode for normal windows */ - if (border_no_shadow) +void +decor_frame_update_shadow (Display *xdisplay, + Screen *screen, + decor_frame_t *frame, + decor_shadow_info_t *info, + decor_shadow_options_t *opt_shadow, + decor_shadow_options_t *opt_no_shadow) +{ + if (frame->border_shadow) { - decor_shadow_destroy (xdisplay, border_no_shadow); - border_no_shadow = NULL; + decor_shadow_destroy (xdisplay, frame->border_shadow); + frame->border_shadow = NULL; } - border_no_shadow = decor_shadow_create (xdisplay, - gdk_x11_screen_get_xscreen (screen), + frame->border_shadow = decor_shadow_create (xdisplay, + screen, + 1, 1, + frame->win_extents.left, + frame->win_extents.right, + frame->win_extents.top + frame->titlebar_height, + frame->win_extents.bottom, + frame->win_extents.left - + TRANSLUCENT_CORNER_SIZE, + frame->win_extents.right - + TRANSLUCENT_CORNER_SIZE, + frame->win_extents.top + frame->titlebar_height - + TRANSLUCENT_CORNER_SIZE, + frame->win_extents.bottom - + TRANSLUCENT_CORNER_SIZE, + opt_shadow, + &frame->window_context, + draw_border_shape, + (void *) info); + if (frame->border_no_shadow) + { + decor_shadow_destroy (xdisplay, frame->border_no_shadow); + frame->border_no_shadow = NULL; + } + + frame->border_no_shadow = decor_shadow_create (xdisplay, + screen, 1, 1, - _win_extents.left, - _win_extents.right, - _win_extents.top + titlebar_height, - _win_extents.bottom, - _win_extents.left - + frame->win_extents.left, + frame->win_extents.right, + frame->win_extents.top + frame->titlebar_height, + frame->win_extents.bottom, + frame->win_extents.left - TRANSLUCENT_CORNER_SIZE, - _win_extents.right - + frame->win_extents.right - TRANSLUCENT_CORNER_SIZE, - _win_extents.top + titlebar_height - + frame->win_extents.top + frame->titlebar_height - TRANSLUCENT_CORNER_SIZE, - _win_extents.bottom - + frame->win_extents.bottom - TRANSLUCENT_CORNER_SIZE, - &opt_no_shadow, - &window_context_no_shadow, + opt_no_shadow, + &frame->window_context_no_shadow, draw_border_shape, 0); - decor_context_t *context = &window_context_no_shadow; - /* Maximized border shadow pixmap mode */ - if (max_border_shadow) + if (frame->max_border_shadow) { - decor_shadow_destroy (xdisplay, max_border_shadow); - max_border_shadow = NULL; + decor_shadow_destroy (xdisplay, frame->max_border_shadow); + frame->max_border_shadow = NULL; } - max_border_shadow = + info->state = (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY | + WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY); + + frame->max_border_shadow = decor_shadow_create (xdisplay, - gdk_x11_screen_get_xscreen (screen), + screen, 1, 1, - _max_win_extents.left, - _max_win_extents.right, - _max_win_extents.top + max_titlebar_height, - _max_win_extents.bottom, - _max_win_extents.left - TRANSLUCENT_CORNER_SIZE, - _max_win_extents.right - TRANSLUCENT_CORNER_SIZE, - _max_win_extents.top + max_titlebar_height - + frame->max_win_extents.left, + frame->max_win_extents.right, + frame->max_win_extents.top + frame->max_titlebar_height, + frame->max_win_extents.bottom, + frame->max_win_extents.left - TRANSLUCENT_CORNER_SIZE, + frame->max_win_extents.right - TRANSLUCENT_CORNER_SIZE, + frame->max_win_extents.top + frame->max_titlebar_height - TRANSLUCENT_CORNER_SIZE, - _max_win_extents.bottom - TRANSLUCENT_CORNER_SIZE, - &opt_shadow, - &max_window_context, + frame->max_win_extents.bottom - TRANSLUCENT_CORNER_SIZE, + opt_shadow, + &frame->max_window_context, draw_border_shape, - (void *) 1); + (void *) info); /* Enforced maximize zero shadow reparenting mode */ - if (max_border_no_shadow) + if (frame->max_border_no_shadow) { - decor_shadow_destroy (xdisplay, max_border_shadow); - max_border_shadow = NULL; + decor_shadow_destroy (xdisplay, frame->max_border_shadow); + frame->max_border_shadow = NULL; } - max_border_no_shadow = + frame->max_border_no_shadow = decor_shadow_create (xdisplay, - gdk_x11_screen_get_xscreen (screen), + screen, 1, 1, - _max_win_extents.left, - _max_win_extents.right, - _max_win_extents.top + max_titlebar_height, - _max_win_extents.bottom, - _max_win_extents.left - TRANSLUCENT_CORNER_SIZE, - _max_win_extents.right - TRANSLUCENT_CORNER_SIZE, - _max_win_extents.top + max_titlebar_height - + frame->max_win_extents.left, + frame->max_win_extents.right, + frame->max_win_extents.top + frame->max_titlebar_height, + frame->max_win_extents.bottom, + frame->max_win_extents.left - TRANSLUCENT_CORNER_SIZE, + frame->max_win_extents.right - TRANSLUCENT_CORNER_SIZE, + frame->max_win_extents.top + frame->max_titlebar_height - TRANSLUCENT_CORNER_SIZE, - _max_win_extents.bottom - TRANSLUCENT_CORNER_SIZE, - &opt_no_shadow, - &max_window_context_no_shadow, + frame->max_win_extents.bottom - TRANSLUCENT_CORNER_SIZE, + opt_no_shadow, + &frame->max_window_context_no_shadow, draw_border_shape, - (void *) 1); + (void *) info); +} - /* Special shadow for the switcher window */ - if (switcher_shadow) - { - decor_shadow_destroy (xdisplay, switcher_shadow); - switcher_shadow = NULL; - } - switcher_shadow = decor_shadow_create (xdisplay, - gdk_x11_screen_get_xscreen (screen), - 1, 1, - _switcher_extents.left, - _switcher_extents.right, - _switcher_extents.top, - _switcher_extents.bottom, - _switcher_extents.left - - TRANSLUCENT_CORNER_SIZE, - _switcher_extents.right - - TRANSLUCENT_CORNER_SIZE, - _switcher_extents.top - - TRANSLUCENT_CORNER_SIZE, - _switcher_extents.bottom - - TRANSLUCENT_CORNER_SIZE, - &opt_shadow, - &switcher_context, - decor_draw_simple, - 0); +typedef struct _tdtd_shadow_options +{ + decor_shadow_options_t *shadow; + decor_shadow_options_t *no_shadow; +} tdtd_shadow_options_t; + +void +frame_update_shadow (decor_frame_t *frame, + decor_shadow_info_t *info, + decor_shadow_options_t *opt_shadow, + decor_shadow_options_t *opt_no_shadow) +{ + gwd_decor_frame_ref (frame); + + (*frame->update_shadow) (gdk_x11_get_default_xdisplay (), + gdk_x11_screen_get_xscreen (gdk_screen_get_default ()), + frame, info, opt_shadow, opt_no_shadow); + + gwd_decor_frame_unref (frame); +} + +void +update_frames_shadows (gpointer key, + gpointer value, + gpointer user_data) +{ + decor_frame_t *frame = (decor_frame_t *) value; + tdtd_shadow_options_t *opts = (tdtd_shadow_options_t *) user_data; + + gwd_decor_frame_ref (frame); + + decor_shadow_info_t *info = malloc (sizeof (decor_shadow_info_t)); + + if (!info) + return; + + info->frame = frame; + info->state = 0; + + frame_update_shadow (frame, info, opts->shadow, opts->no_shadow); + + gwd_decor_frame_unref (frame); + + free (info); + info = NULL; + +} + +int +update_shadow (void) +{ + decor_shadow_options_t opt_shadow; + decor_shadow_options_t opt_no_shadow; + tdtd_shadow_options_t *opts; + + opts = malloc (sizeof (tdtd_shadow_options_t)); + + if (!opts) + return 0; + + opt_shadow.shadow_radius = settings->shadow_radius; + opt_shadow.shadow_opacity = settings->shadow_opacity; + + memcpy (opt_shadow.shadow_color, settings->shadow_color, sizeof (settings->shadow_color)); + + opt_shadow.shadow_offset_x = settings->shadow_offset_x; + opt_shadow.shadow_offset_y = settings->shadow_offset_y; + + opt_no_shadow.shadow_radius = 0; + opt_no_shadow.shadow_opacity = 0; + + opt_no_shadow.shadow_offset_x = 0; + opt_no_shadow.shadow_offset_y = 0; + + opts->shadow = &opt_shadow; + opts->no_shadow = &opt_no_shadow; + + gwd_frames_foreach (update_frames_shadows, (gpointer ) opts); + + if (opts) + free (opts); return 1; } @@ -821,7 +1034,6 @@ update_window_decoration (WnckWindow *win) { decor_t *d = g_object_get_data (G_OBJECT (win), "decor"); - /* Handle normally decorated windows */ if (d->decorated) { /* force size update */ @@ -831,22 +1043,6 @@ update_window_decoration (WnckWindow *win) update_window_decoration_size (win); update_event_windows (win); } - /* Handle switcher windows */ - else - { - Window xid = wnck_window_get_xid (win); - Window select; - - if (get_window_prop (xid, select_window_atom, &select)) - { - /* force size update */ - d->context = NULL; - d->width = d->height = 0; - switcher_width = switcher_height = 0; - - update_switcher_window (win, select); - } - } } /* @@ -941,7 +1137,9 @@ update_default_decorations (GdkScreen *screen) decor_t d; gint nQuad; decor_quad_t quads[N_QUADS_MAX]; - decor_extents_t extents = _win_extents; + decor_frame_t *frame; + decor_frame_t *bare_frame = gwd_get_decor_frame ("bare"); + decor_extents_t extents; xroot = RootWindowOfScreen (gdk_x11_screen_get_xscreen (screen)); @@ -949,18 +1147,18 @@ update_default_decorations (GdkScreen *screen) normalAtom = XInternAtom (xdisplay, DECOR_NORMAL_ATOM_NAME, FALSE); activeAtom = XInternAtom (xdisplay, DECOR_ACTIVE_ATOM_NAME, FALSE); - if (no_border_shadow) + if (bare_frame->border_shadow) { decor_layout_t layout; - decor_get_default_layout (&shadow_context, 1, 1, &layout); + decor_get_default_layout (&bare_frame->window_context, 1, 1, &layout); - nQuad = decor_set_lSrStSbS_window_quads (quads, &shadow_context, + nQuad = decor_set_lSrStSbS_window_quads (quads, &bare_frame->window_context, &layout); - decor_quads_to_property (data, no_border_shadow->pixmap, - &_shadow_extents, &_shadow_extents, - &_shadow_extents, &_shadow_extents, + decor_quads_to_property (data, bare_frame->border_shadow->pixmap, + &bare_frame->win_extents, &bare_frame->win_extents, + &bare_frame->win_extents, &bare_frame->win_extents, 0, 0, quads, nQuad); XChangeProperty (xdisplay, xroot, @@ -995,20 +1193,28 @@ update_default_decorations (GdkScreen *screen) } if (minimal) + { + gwd_decor_frame_unref (bare_frame); return; + } memset (&d, 0, sizeof (d)); - d.context = &window_context; - d.shadow = border_shadow; - d.layout = pango_layout_new (pango_context); + frame = gwd_get_decor_frame ("default"); + extents = frame->win_extents; + + d.context = &frame->window_context; + d.shadow = frame->border_shadow; + d.layout = pango_layout_new (frame->pango_context); decor_get_default_layout (d.context, 1, 1, &d.border_layout); d.width = d.border_layout.width; d.height = d.border_layout.height; - extents.top += titlebar_height; + d.frame = frame; + + extents.top += frame->titlebar_height; d.draw = theme_draw_window_decoration; @@ -1018,7 +1224,7 @@ update_default_decorations (GdkScreen *screen) nQuad = decor_set_lSrStSbS_window_quads (quads, d.context, &d.border_layout); - decor_normal_pixmap = create_pixmap (d.width, d.height, 32); + decor_normal_pixmap = create_pixmap (d.width, d.height, frame->style_window_rgba); if (decor_normal_pixmap) { @@ -1046,7 +1252,7 @@ update_default_decorations (GdkScreen *screen) if (decor_active_pixmap) g_object_unref (G_OBJECT (decor_active_pixmap)); - decor_active_pixmap = create_pixmap (d.width, d.height, 32); + decor_active_pixmap = create_pixmap (d.width, d.height, frame->style_window_rgba); if (decor_active_pixmap) { @@ -1071,6 +1277,9 @@ update_default_decorations (GdkScreen *screen) BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad); } + gwd_decor_frame_unref (frame); + gwd_decor_frame_unref (bare_frame); + if (d.layout) g_object_unref (G_OBJECT (d.layout)); } diff --git a/gtk/window-decorator/decorprops.c b/gtk/window-decorator/decorprops.c index b6b3820..92cd36d 100644 --- a/gtk/window-decorator/decorprops.c +++ b/gtk/window-decorator/decorprops.c @@ -1,3 +1,28 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + * + * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com> + * Frames Management: Copright © 2011 Canonical Ltd. + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> + */ + #include "gtk-window-decorator.h" void @@ -6,7 +31,7 @@ decor_update_window_property (decor_t *d) long data[256]; Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - decor_extents_t extents = _win_extents; + decor_extents_t extents = d->frame->win_extents; gint nQuad; decor_quad_t quads[N_QUADS_MAX]; int w, h; @@ -27,7 +52,7 @@ decor_update_window_property (decor_t *d) &d->border_layout, stretch_offset); - extents.top += titlebar_height; + extents.top += d->frame->titlebar_height; if (d->frame_window) { @@ -36,7 +61,8 @@ decor_update_window_property (decor_t *d) else { decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap), - &extents, &extents, &extents, &extents, + &extents, &extents, + &extents, &extents, ICON_SPACE + d->button_width, 0, quads, nQuad); @@ -101,20 +127,20 @@ decor_update_switcher_property (decor_t *d) GtkStyle *style; long fgColor[4]; - nQuad = decor_set_lSrStSbX_window_quads (quads, &switcher_context, + nQuad = decor_set_lSrStSbX_window_quads (quads, &d->frame->window_context, &d->border_layout, d->border_layout.top.x2 - d->border_layout.top.x1 - - switcher_context.extents.left - - switcher_context.extents.right - + d->frame->window_context.extents.left - + d->frame->window_context.extents.right - 32); decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap), - &_switcher_extents, &_switcher_extents, - &_switcher_extents, &_switcher_extents, + &d->frame->win_extents, &d->frame->win_extents, + &d->frame->win_extents, &d->frame->win_extents, 0, 0, quads, nQuad); - style = gtk_widget_get_style (style_window_rgba); + style = gtk_widget_get_style (d->frame->style_window_rgba); fgColor[0] = style->fg[GTK_STATE_NORMAL].red; fgColor[1] = style->fg[GTK_STATE_NORMAL].green; diff --git a/gtk/window-decorator/events.c b/gtk/window-decorator/events.c index 1faec8b..73e44ef 100644 --- a/gtk/window-decorator/events.c +++ b/gtk/window-decorator/events.c @@ -1,3 +1,28 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + * + * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com> + * Frames Management: Copright © 2011 Canonical Ltd. + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> + */ + #include "gtk-window-decorator.h" void @@ -387,7 +412,7 @@ void handle_mouse_wheel_title_event (WnckWindow *win, unsigned int button) { - switch (wheel_action) { + switch (settings->wheel_action) { case WHEEL_ACTION_SHADE: if (button == 4) { @@ -436,7 +461,7 @@ title_event (WnckWindow *win, dist (gtkwd_event->x, gtkwd_event->y, last_button_x, last_button_y) < DOUBLE_CLICK_DISTANCE) { - handle_title_button_event (win, double_click_action, + handle_title_button_event (win, settings->double_click_action, gtkwd_event); last_button_num = 0; @@ -460,12 +485,12 @@ title_event (WnckWindow *win, } else if (gtkwd_event->button == 2) { - handle_title_button_event (win, middle_click_action, + handle_title_button_event (win, settings->middle_click_action, gtkwd_event); } else if (gtkwd_event->button == 3) { - handle_title_button_event (win, right_click_action, + handle_title_button_event (win, settings->right_click_action, gtkwd_event); } else if (gtkwd_event->button == 4 || @@ -534,11 +559,11 @@ frame_common_event (WnckWindow *win, restack_window (win, Above); break; case 2: - handle_title_button_event (win, middle_click_action, + handle_title_button_event (win, settings->middle_click_action, gtkwd_event); break; case 3: - handle_title_button_event (win, right_click_action, + handle_title_button_event (win, settings->right_click_action, gtkwd_event); break; } @@ -955,7 +980,8 @@ event_filter_func (GdkXEvent *gdkxevent, if (screen) { - shadow_property_changed (screen); + if (shadow_property_changed (screen)) + decorations_changed (screen); } } else if (xevent->xproperty.atom == mwm_hints_atom) @@ -1138,7 +1164,7 @@ selection_event_filter_func (GdkXEvent *gdkxevent, case SelectionClear: status = decor_handle_selection_clear (xdisplay, xevent, 0); if (status == DECOR_SELECTION_GIVE_UP) - exit (0); + gtk_main_quit (); default: break; } diff --git a/gtk/window-decorator/forcequit.c b/gtk/window-decorator/forcequit.c index 93ed2f0..adc051e 100644 --- a/gtk/window-decorator/forcequit.c +++ b/gtk/window-decorator/forcequit.c @@ -1,3 +1,28 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + * + * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com> + * Frames Management: Copright © 2011 Canonical Ltd. + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> + */ + #include "gtk-window-decorator.h" static char * diff --git a/gtk/window-decorator/frames.c b/gtk/window-decorator/frames.c new file mode 100644 index 0000000..06482c5 --- /dev/null +++ b/gtk/window-decorator/frames.c @@ -0,0 +1,316 @@ +/* + * Copyright © 2011 Canonical Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authored by: + * Sam Spilsbury <sam.spilsbury@canonical.com> + */ + +#include "gtk-window-decorator.h" + +typedef struct _decor_frame_type_info +{ + create_frame_proc create_func; + destroy_frame_proc destroy_func; +} decor_frame_type_info_t; + +GHashTable *frame_info_table; +GHashTable *frames_table; + +void +decor_frame_refresh (decor_frame_t *frame) +{ + decor_shadow_options_t opt_shadow; + decor_shadow_options_t opt_no_shadow; + decor_shadow_info_t *info; + + update_style (frame->style_window_rgba); + update_style (frame->style_window_rgb); + + gchar *str = settings->font; + + set_frame_scale (frame, str); + + str = NULL; + + frame_update_titlebar_font (frame); + + if (strcmp (frame->type, "switcher") != 0 && + strcmp (frame->type, "bare") != 0) + (*theme_update_border_extents) (frame); + + opt_shadow.shadow_radius = settings->shadow_radius; + opt_shadow.shadow_opacity = settings->shadow_opacity; + + memcpy (opt_shadow.shadow_color, settings->shadow_color, sizeof (settings->shadow_color)); + + opt_shadow.shadow_offset_x = settings->shadow_offset_x; + opt_shadow.shadow_offset_y = settings->shadow_offset_y; + + opt_no_shadow.shadow_radius = 0; + opt_no_shadow.shadow_opacity = 0; + + opt_no_shadow.shadow_offset_x = 0; + opt_no_shadow.shadow_offset_y = 0; + + info = malloc (sizeof (decor_shadow_info_t)); + + if (!info) + return; + + info->frame = frame; + info->state = 0; + + frame_update_shadow (frame, info, &opt_shadow, &opt_no_shadow); + + free (info); + info = NULL; +} + +decor_frame_t * +gwd_get_decor_frame (const gchar *frame_name) +{ + decor_frame_t *frame = g_hash_table_lookup (frames_table, frame_name); + + if (!frame) + { + /* Frame not found, look up frame type in the frame types + * hash table and create a new one */ + + decor_frame_type_info_t *info = g_hash_table_lookup (frame_info_table, frame_name); + + if (!info) + g_critical ("Could not find frame info %s in frame type table", frame_name); + + frame = (*info->create_func) (frame_name); + + if (!frame) + g_critical ("Could not allocate frame %s", frame_name); + + g_hash_table_insert (frames_table, frame->type, frame); + + gwd_decor_frame_ref (frame); + + decor_frame_refresh (frame); + } + else + gwd_decor_frame_ref (frame); + + return frame; +} + +decor_frame_t * +gwd_decor_frame_ref (decor_frame_t *frame) +{ + frame->refcount++; + return frame; +} + +decor_frame_t * +gwd_decor_frame_unref (decor_frame_t *frame) +{ + frame->refcount--; + + if (frame->refcount == 0) + { + decor_frame_type_info_t *info = g_hash_table_lookup (frame_info_table, frame->type); + + if (!info) + g_critical ("Couldn't find %s in frame info table", frame->type); + + if(!g_hash_table_remove (frames_table, frame->type)) + g_critical ("Could not remove frame type %s from hash_table!", frame->type); + + (*info->destroy_func) (frame); + } + return frame; +} + +gboolean +gwd_decor_frame_add_type (const gchar *name, + create_frame_proc create_func, + destroy_frame_proc destroy_func) +{ + decor_frame_type_info_t *frame_type = malloc (sizeof (decor_frame_type_info_t)); + + if (!frame_type) + return FALSE; + + frame_type->create_func = create_func; + frame_type->destroy_func = destroy_func; + + g_hash_table_insert (frame_info_table, strdup (name), frame_type); + + return TRUE; +} + +void +gwd_decor_frame_remove_type (const gchar *name) +{ + g_hash_table_remove (frame_info_table, name); +} + +void +gwd_frames_foreach (GHFunc foreach_func, + gpointer user_data) +{ + g_hash_table_foreach (frames_table, foreach_func, user_data); +} + +void +gwd_process_frames (GHFunc foreach_func, + const gchar *frame_keys[], + gint frame_keys_num, + gpointer user_data) +{ + gint i = 0; + + for (; i < frame_keys_num; i++) + { + gpointer frame = g_hash_table_lookup (frames_table, frame_keys[i]); + + if (!frame) + continue; + + (*foreach_func) ((gpointer) frame_keys[i], frame, user_data); + } +} + +void +destroy_frame_type (gpointer data) +{ + decor_frame_type_info_t *info = (decor_frame_type_info_t *) data; + + if (info) + { + /* TODO: Destroy all frames with this type using + * the frame destroy function */ + } + + free (info); +} + +decor_frame_t * +decor_frame_new (const gchar *type) +{ + GdkScreen *gdkscreen = gdk_screen_get_default (); + GdkColormap *colormap; + decor_frame_t *frame = malloc (sizeof (decor_frame_t)); + + if (!frame) + { + g_critical ("Couldn't allocate frame!"); + return NULL; + } + + frame->type = strdup (type); + frame->refcount = 0; + frame->titlebar_height = 17; + frame->max_titlebar_height = 17; + frame->border_shadow = NULL; + frame->border_no_shadow = NULL; + frame->max_border_no_shadow = NULL; + frame->max_border_shadow = NULL; + frame->titlebar_font = NULL; + + frame->style_window_rgba = gtk_window_new (GTK_WINDOW_POPUP); + + colormap = gdk_screen_get_rgba_colormap (gdkscreen); + if (colormap) + gtk_widget_set_colormap (frame->style_window_rgba, colormap); + + gtk_widget_realize (frame->style_window_rgba); + + gtk_widget_set_size_request (frame->style_window_rgba, 0, 0); + gtk_window_move (GTK_WINDOW (frame->style_window_rgba), -100, -100); + gtk_widget_show_all (frame->style_window_rgba); + + frame->pango_context = gtk_widget_create_pango_context (frame->style_window_rgba); + + g_signal_connect_data (frame->style_window_rgba, "style-set", + G_CALLBACK (style_changed), + (gpointer) frame->pango_context, 0, 0); + + frame->style_window_rgb = gtk_window_new (GTK_WINDOW_POPUP); + + colormap = gdk_screen_get_rgb_colormap (gdkscreen); + if (colormap) + gtk_widget_set_colormap (frame->style_window_rgb, colormap); + + gtk_widget_realize (frame->style_window_rgb); + + gtk_widget_set_size_request (frame->style_window_rgb, 0, 0); + gtk_window_move (GTK_WINDOW (frame->style_window_rgb), -100, -100); + gtk_widget_show_all (frame->style_window_rgb); + + g_signal_connect_data (frame->style_window_rgb, "style-set", + G_CALLBACK (style_changed), + (gpointer) frame->pango_context, 0, 0); + + return frame; +} + +void +decor_frame_destroy (decor_frame_t *frame) +{ + Display *xdisplay = gdk_x11_get_default_xdisplay (); + + if (frame->border_shadow) + decor_shadow_destroy (xdisplay, frame->border_shadow); + + if (frame->border_no_shadow) + decor_shadow_destroy (xdisplay, frame->border_no_shadow); + + if (frame->max_border_shadow) + decor_shadow_destroy (xdisplay, frame->max_border_shadow); + + if (frame->max_border_no_shadow) + decor_shadow_destroy (xdisplay, frame->max_border_no_shadow); + + if (frame->style_window_rgba) + gtk_widget_destroy (GTK_WIDGET (frame->style_window_rgba)); + + if (frame->style_window_rgb) + gtk_widget_destroy (GTK_WIDGET (frame->style_window_rgb)); + + if (frame->pango_context) + g_object_unref (G_OBJECT (frame->pango_context)); + + if (frame->titlebar_font) + pango_font_description_free (frame->titlebar_font); + + if (frame) + free (frame->type); + + free (frame); +} + +void +initialize_decorations () +{ + frame_info_table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, destroy_frame_type); + + gwd_decor_frame_add_type ("default", create_normal_frame, destroy_normal_frame); + gwd_decor_frame_add_type ("normal", create_normal_frame, destroy_normal_frame); + gwd_decor_frame_add_type ("dialog", create_normal_frame, destroy_normal_frame); + gwd_decor_frame_add_type ("menu", create_normal_frame, destroy_normal_frame); + gwd_decor_frame_add_type ("utility", create_normal_frame, destroy_normal_frame); + gwd_decor_frame_add_type ("switcher", create_switcher_frame, destroy_switcher_frame); + gwd_decor_frame_add_type ("bare", create_bare_frame, destroy_bare_frame); + + frames_table = g_hash_table_new (g_str_hash, g_str_equal); +} diff --git a/gtk/window-decorator/gdk.c b/gtk/window-decorator/gdk.c index fe7d63a..77ead1e 100644 --- a/gtk/window-decorator/gdk.c +++ b/gtk/window-decorator/gdk.c @@ -1,7 +1,28 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + */ + #include "gtk-window-decorator.h" GdkPixmap * -pixmap_new_from_pixbuf (GdkPixbuf *pixbuf, int depth) +pixmap_new_from_pixbuf (GdkPixbuf *pixbuf, GtkWidget *parent) { GdkPixmap *pixmap; guint width, height; @@ -10,7 +31,7 @@ pixmap_new_from_pixbuf (GdkPixbuf *pixbuf, int depth) width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); - pixmap = create_pixmap (width, height, depth); + pixmap = create_pixmap (width, height, parent); if (!pixmap) return NULL; @@ -71,17 +92,15 @@ get_format_for_drawable (decor_t *d, GdkDrawable *drawable) } GdkPixmap * -create_pixmap (int w, - int h, - int depth) +create_pixmap (int w, + int h, + GtkWidget *parent_style_window) { - GtkWidget *widget; GdkWindow *window; if (w == 0 || h == 0) abort (); - widget = (depth > 24) ? style_window_rgba : style_window_rgb; - window = gtk_widget_get_window (widget); - return gdk_pixmap_new (GDK_DRAWABLE (window), w, h, depth); -}
\ No newline at end of file + window = gtk_widget_get_window (parent_style_window); + return gdk_pixmap_new (GDK_DRAWABLE (window), w, h, -1 /* CopyFromParent */); +} diff --git a/gtk/window-decorator/gtk-window-decorator.c b/gtk/window-decorator/gtk-window-decorator.c index 93e38db..86e684f 100644 --- a/gtk/window-decorator/gtk-window-decorator.c +++ b/gtk/window-decorator/gtk-window-decorator.c @@ -17,80 +17,20 @@ * Boston, MA 02111-1307, USA. * * Author: David Reveman <davidr@novell.com> + * + * 2D Mode: Copyright © 2009 Sam Spilsbury <smspillaz@gmail.com> + * Frames Management: Copright © 2010 Canonical Ltd. + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> */ #include "gtk-window-decorator.h" gboolean minimal = FALSE; -double decoration_alpha = 0.5; - #define SWITCHER_SPACE 40 -decor_extents_t _shadow_extents = { 0, 0, 0, 0 }; -decor_extents_t _win_extents = { 6, 6, 6, 6 }; -decor_extents_t _max_win_extents = { 6, 6, 4, 6 }; -decor_extents_t _default_win_extents = { 6, 6, 6, 6 }; -decor_extents_t _switcher_extents = { 6, 6, 6, 6 + SWITCHER_SPACE }; - -int titlebar_height = 17; -int max_titlebar_height = 17; - -decor_context_t window_context = { - { 0, 0, 0, 0 }, - 6, 6, 4, 6, - 0, 0, 0, 0 -}; - -decor_context_t max_window_context = { - { 0, 0, 0, 0 }, - 6, 6, 4, 6, - 0, 0, 0, 0 -}; - -decor_context_t window_context_no_shadow = { - { 0, 0, 0, 0 }, - 6, 6, 4, 6, - 0, 0, 0, 0 -}; - -decor_context_t max_window_context_no_shadow = { - { 0, 0, 0, 0 }, - 6, 6, 4, 6, - 0, 0, 0, 0 -}; - -decor_context_t switcher_context = { - { 0, 0, 0, 0 }, - 6, 6, 6, 6 + SWITCHER_SPACE, - 0, 0, 0, 0 -}; - -decor_context_t shadow_context = { - { 0, 0, 0, 0 }, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; - -gdouble shadow_radius = SHADOW_RADIUS; -gdouble shadow_opacity = SHADOW_OPACITY; -gushort shadow_color[3] = { - SHADOW_COLOR_RED, - SHADOW_COLOR_GREEN, - SHADOW_COLOR_BLUE -}; -gint shadow_offset_x = SHADOW_OFFSET_X; -gint shadow_offset_y = SHADOW_OFFSET_Y; - guint cmdline_options = 0; -decor_shadow_t *no_border_shadow = NULL; -decor_shadow_t *border_shadow = NULL; -decor_shadow_t *max_border_shadow = NULL; -decor_shadow_t *border_no_shadow = NULL; -decor_shadow_t *max_border_no_shadow = NULL; -decor_shadow_t *switcher_shadow = NULL; - GdkPixmap *decor_normal_pixmap = NULL; GdkPixmap *decor_active_pixmap = NULL; @@ -103,10 +43,8 @@ Atom restack_window_atom; Atom select_window_atom; Atom mwm_hints_atom; Atom switcher_fg_atom; - Atom compiz_shadow_info_atom; Atom compiz_shadow_color_atom; - Atom toolkit_action_atom; Atom toolkit_action_window_menu_atom; Atom toolkit_action_force_quit_dialog_atom; @@ -140,17 +78,18 @@ struct _pos pos[3][3] = { { 6, 2, 16, 16, 0, 0, 0, 0, 0, 0 } }; +const gchar * window_type_frames[WINDOW_TYPE_FRAMES_NUM] = { + "normal", "dialog", "menu", "utility" +}; + char *program_name; -GtkWidget *style_window_rgba; -GtkWidget *style_window_rgb; GtkWidget *switcher_label; GHashTable *frame_table; GtkWidget *action_menu = NULL; gboolean action_menu_mapped = FALSE; decor_color_t _title_color[2]; -PangoContext *pango_context; gint double_click_timeout = 250; GtkWidget *tip_window; @@ -161,47 +100,71 @@ gint tooltip_timer_tag = 0; GSList *draw_list = NULL; guint draw_idle_id = 0; -PangoFontDescription *titlebar_font = NULL; -gboolean use_system_font = FALSE; -gint text_height; - -gint blur_type = BLUR_TYPE_NONE; - -GdkPixmap *switcher_pixmap = NULL; -GdkPixmap *switcher_buffer_pixmap = NULL; -gint switcher_width; -gint switcher_height; Window switcher_selected_window = None; decor_t *switcher_window = NULL; XRenderPictFormat *xformat_rgba; XRenderPictFormat *xformat_rgb; +decor_settings_t *settings; + int main (int argc, char *argv[]) { - GdkDisplay *gdkdisplay; - Display *xdisplay; - GdkScreen *gdkscreen; - WnckScreen *screen; - gint i, j, status; - gboolean replace = FALSE; - unsigned int nchildren; - Window root_ret, parent_ret; - Window *children = NULL; + GdkDisplay *gdkdisplay; + Display *xdisplay; + GdkScreen *gdkscreen; + WnckScreen *screen; + gint i, j, status; + gboolean replace = FALSE; + unsigned int nchildren; + Window root_ret, parent_ret; + Window *children = NULL; + GList *windows, *win; + decor_frame_t *default_p, *bare_p, *switcher_p; #ifdef USE_METACITY char *meta_theme = NULL; + MetaTheme *theme = NULL; #endif program_name = argv[0]; + settings = malloc (sizeof (decor_settings_t)); + + if (!settings) + return 1; + gtk_init (&argc, &argv); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); + settings->blur_type = BLUR_TYPE_NONE; + settings->use_system_font = FALSE; + + settings->shadow_radius = SHADOW_RADIUS; + settings->shadow_opacity = SHADOW_OPACITY; + settings->shadow_color[0] = SHADOW_COLOR_RED; + settings->shadow_color[1] = SHADOW_COLOR_GREEN; + settings->shadow_color[2] = SHADOW_COLOR_BLUE; + settings->shadow_offset_x = SHADOW_OFFSET_X; + settings->shadow_offset_y = SHADOW_OFFSET_Y; + settings->decoration_alpha = 0.5; + +#ifdef USE_METACITY + + settings->meta_opacity = META_OPACITY; + settings->meta_shade_opacity = META_SHADE_OPACITY; + settings->meta_active_opacity = META_ACTIVE_OPACITY; + settings->meta_active_shade_opacity = META_ACTIVE_SHADE_OPACITY; + + settings->meta_button_layout_set = FALSE; +#endif + + settings->font = strdup ("Sans Bold 12"); + for (i = 0; i < argc; i++) { if (strcmp (argv[i], "--minimal") == 0) @@ -217,9 +180,9 @@ main (int argc, char *argv[]) if (argc > ++i) { if (strcmp (argv[i], "titlebar") == 0) - blur_type = BLUR_TYPE_TITLEBAR; + settings->blur_type = BLUR_TYPE_TITLEBAR; else if (strcmp (argv[i], "all") == 0) - blur_type = BLUR_TYPE_ALL; + settings->blur_type = BLUR_TYPE_ALL; } cmdline_options |= CMDLINE_BLUR; } @@ -228,23 +191,23 @@ main (int argc, char *argv[]) else if (strcmp (argv[i], "--opacity") == 0) { if (argc > ++i) - meta_opacity = atof (argv[i]); + settings->meta_opacity = atof (argv[i]); cmdline_options |= CMDLINE_OPACITY; } else if (strcmp (argv[i], "--no-opacity-shade") == 0) { - meta_shade_opacity = FALSE; + settings->meta_shade_opacity = FALSE; cmdline_options |= CMDLINE_OPACITY_SHADE; } else if (strcmp (argv[i], "--active-opacity") == 0) { if (argc > ++i) - meta_active_opacity = atof (argv[i]); + settings->meta_active_opacity = atof (argv[i]); cmdline_options |= CMDLINE_ACTIVE_OPACITY; } else if (strcmp (argv[i], "--no-active-opacity-shade") == 0) { - meta_active_shade_opacity = FALSE; + settings->meta_active_shade_opacity = FALSE; cmdline_options |= CMDLINE_ACTIVE_OPACITY_SHADE; } else if (strcmp (argv[i], "--metacity-theme") == 0) @@ -277,27 +240,6 @@ main (int argc, char *argv[]) } } - theme_draw_window_decoration = draw_window_decoration; - theme_calc_decoration_size = calc_decoration_size; - theme_update_border_extents = update_border_extents; - theme_get_event_window_position = get_event_window_position; - theme_get_button_position = get_button_position; - -#ifdef USE_METACITY - if (meta_theme) - { - meta_theme_set_current (meta_theme, TRUE); - if (meta_theme_get_current ()) - { - theme_draw_window_decoration = meta_draw_window_decoration; - theme_calc_decoration_size = meta_calc_decoration_size; - theme_update_border_extents = meta_update_border_extents; - theme_get_event_window_position = meta_get_event_window_position; - theme_get_button_position = meta_get_button_position; - } - } -#endif - gdkdisplay = gdk_display_get_default (); xdisplay = gdk_x11_display_get_xdisplay (gdkdisplay); gdkscreen = gdk_display_get_default_screen (gdkdisplay); @@ -356,6 +298,49 @@ main (int argc, char *argv[]) return 1; } + screen = wnck_screen_get_default (); + + initialize_decorations (); + + if (!init_settings (screen)) + { + free (settings); + fprintf (stderr, "%s: Failed to get necessary gtk settings\n", argv[0]); + return 1; + } + + theme_draw_window_decoration = draw_window_decoration; + theme_calc_decoration_size = calc_decoration_size; + theme_update_border_extents = update_border_extents; + theme_get_event_window_position = get_event_window_position; + theme_get_button_position = get_button_position; + theme_get_title_scale = get_title_scale; + +#ifdef USE_METACITY + if (meta_theme) + { + meta_theme_set_current (meta_theme, TRUE); + + theme = meta_theme_get_current (); + + if (!theme) + g_warning ("specified a theme that does not exist! falling back to cairo decoration\n"); + } + else + theme = meta_theme_get_current (); + + if (theme) + { + fprintf (stderr, "setting procs\n"); + theme_draw_window_decoration = meta_draw_window_decoration; + theme_calc_decoration_size = meta_calc_decoration_size; + theme_update_border_extents = meta_update_border_extents; + theme_get_event_window_position = meta_get_event_window_position; + theme_get_button_position = meta_get_button_position; + theme_get_title_scale = meta_get_title_scale; + } +#endif + for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) @@ -373,19 +358,19 @@ main (int argc, char *argv[]) if (!create_tooltip_window ()) { + free (settings); fprintf (stderr, "%s, Couldn't create tooltip window\n", argv[0]); return 1; } - screen = wnck_screen_get_default (); wnck_set_client_type (WNCK_CLIENT_TYPE_PAGER); gdk_window_add_filter (NULL, selection_event_filter_func, NULL); - if (!minimal) - { + if (!minimal) + { GdkWindow *root = gdk_window_foreign_new_for_display (gdkdisplay, gdk_x11_get_default_root_xwindow ()); @@ -418,11 +403,12 @@ main (int argc, char *argv[]) connect_screen (screen); } - if (!init_settings (screen)) - { - fprintf (stderr, "%s: Failed to get necessary gtk settings\n", argv[0]); - return 1; - } + /* Keep the default, bare and switcher decorations around + * since otherwise they will be spuriously recreated */ + + default_p = gwd_get_decor_frame ("default"); + bare_p = gwd_get_decor_frame ("bare"); + switcher_p = gwd_get_decor_frame ("switcher"); decor_set_dm_check_hint (xdisplay, gdk_screen_get_number (gdkscreen), WINDOW_DECORATION_TYPE_PIXMAP | @@ -432,5 +418,33 @@ main (int argc, char *argv[]) gtk_main (); + win = windows = wnck_screen_get_windows (screen); + + while (win != NULL) + { + WnckWindow *w = (WnckWindow *) win->data; + + window_closed (screen, w); + } + + g_list_free (windows); + + if (screen) + g_object_unref (screen); + + if (tip_window) + gtk_widget_destroy (GTK_WIDGET (tip_window)); + + if (tip_label) + gtk_widget_destroy (GTK_WIDGET (tip_label)); + + gwd_decor_frame_unref (default_p); + gwd_decor_frame_unref (bare_p); + gwd_decor_frame_unref (switcher_p); + + g_free (settings->font); + + free (settings); + return 0; } diff --git a/gtk/window-decorator/gtk-window-decorator.h b/gtk/window-decorator/gtk-window-decorator.h index 2bd8669..ab90085 100644 --- a/gtk/window-decorator/gtk-window-decorator.h +++ b/gtk/window-decorator/gtk-window-decorator.h @@ -1,3 +1,28 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + * + * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com> + * Frames Management: Copright © 2011 Canonical Ltd. + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> + */ + #ifndef _GTK_WINDOW_DECORATOR_H #define _GTK_WINDOW_DECORATOR_H #ifdef HAVE_CONFIG_H @@ -210,62 +235,45 @@ enum { WHEEL_ACTION_SHADE }; +typedef struct _decor_settings { + int double_click_action; + int middle_click_action; + int right_click_action; + int wheel_action; + gdouble shadow_radius; + gdouble shadow_opacity; + gushort shadow_color[3]; + gint shadow_offset_x; + gint shadow_offset_y; +#ifdef USE_METACITY + double meta_opacity; + gboolean meta_shade_opacity; + double meta_active_opacity; + gboolean meta_active_shade_opacity; + + gboolean meta_button_layout_set; + MetaButtonLayout meta_button_layout; +#endif + double decoration_alpha; + gboolean use_system_font; + gint blur_type; + gchar *font; +} decor_settings_t; + #define DOUBLE_CLICK_ACTION_DEFAULT CLICK_ACTION_MAXIMIZE #define MIDDLE_CLICK_ACTION_DEFAULT CLICK_ACTION_LOWER #define RIGHT_CLICK_ACTION_DEFAULT CLICK_ACTION_MENU #define WHEEL_ACTION_DEFAULT WHEEL_ACTION_NONE -int double_click_action; -int middle_click_action; -int right_click_action; -int wheel_action; - extern gboolean minimal; -extern double decoration_alpha; - -#define SWITCHER_SPACE 40 - -extern decor_extents_t _shadow_extents; -extern decor_extents_t _win_extents; -extern decor_extents_t _max_win_extents; -extern decor_extents_t _default_win_extents; -extern decor_extents_t _switcher_extents; - -extern int titlebar_height; -extern int max_titlebar_height; - -extern decor_context_t window_context; -extern decor_context_t window_context_no_shadow; -extern decor_context_t max_window_context; -extern decor_context_t max_window_context_no_shadow; -extern decor_context_t switcher_context; -extern decor_context_t shadow_context; +extern decor_settings_t *settings; -extern gdouble shadow_radius; -extern gdouble shadow_opacity; -extern gushort shadow_color[3]; -extern gint shadow_offset_x; -extern gint shadow_offset_y; -#ifdef USE_METACITY -extern double meta_opacity; -extern gboolean meta_shade_opacity; -extern double meta_active_opacity; -extern gboolean meta_active_shade_opacity; - -extern gboolean meta_button_layout_set; -extern MetaButtonLayout meta_button_layout; -#endif +#define SWITCHER_SPACE 40 extern guint cmdline_options; -extern decor_shadow_t *no_border_shadow; -extern decor_shadow_t *border_shadow; -extern decor_shadow_t *border_no_shadow; -extern decor_shadow_t *max_border_shadow; -extern decor_shadow_t *max_border_no_shadow; -extern decor_shadow_t *switcher_shadow; - +/* default pixmaps FIXME: remove */ extern GdkPixmap *decor_normal_pixmap; extern GdkPixmap *decor_active_pixmap; @@ -278,7 +286,8 @@ extern Atom restack_window_atom; extern Atom select_window_atom; extern Atom mwm_hints_atom; extern Atom switcher_fg_atom; - +extern Atom compiz_shadow_info_atom; +extern Atom compiz_shadow_color_atom; extern Atom toolkit_action_atom; extern Atom toolkit_action_window_menu_atom; extern Atom toolkit_action_force_quit_dialog_atom; @@ -351,8 +360,52 @@ typedef struct { event_callback callback; } event_window; +typedef struct _decor_frame decor_frame_t; +typedef struct _decor_shadow_info decor_shadow_info_t; + +struct _decor_shadow_info +{ + decor_frame_t *frame; + unsigned int state; +}; + +typedef void (*frame_update_shadow_proc) (Display *display, + Screen *screen, + decor_frame_t *frame, + decor_shadow_info_t *info, + decor_shadow_options_t *opt_shadow, + decor_shadow_options_t *opt_no_shadow); + +typedef decor_frame_t * (*create_frame_proc) (const gchar *); +typedef void (*destroy_frame_proc) (decor_frame_t *); + +struct _decor_frame { + decor_extents_t win_extents; + decor_extents_t max_win_extents; + int titlebar_height; + int max_titlebar_height; + decor_shadow_t *border_shadow; + decor_shadow_t *border_no_shadow; + decor_shadow_t *max_border_shadow; + decor_shadow_t *max_border_no_shadow; + decor_context_t window_context; + decor_context_t window_context_no_shadow; + decor_context_t max_window_context; + decor_context_t max_window_context_no_shadow; + PangoFontDescription *titlebar_font; + PangoContext *pango_context; + GtkWidget *style_window_rgba; + GtkWidget *style_window_rgb; + gint text_height; + gchar *type; + + frame_update_shadow_proc update_shadow; + gint refcount; +}; + typedef struct _decor { WnckWindow *win; + decor_frame_t *frame; event_window event_windows[3][3]; event_window button_windows[BUTTON_NUM]; Box *last_pos_entered; @@ -395,7 +448,7 @@ gboolean (*theme_calc_decoration_size) (decor_t *d, int text_width, int *width, int *height); -void (*theme_update_border_extents) (gint text_height); +void (*theme_update_border_extents) (decor_frame_t *frame); void (*theme_get_event_window_position) (decor_t *d, gint i, gint j, @@ -413,20 +466,24 @@ gboolean (*theme_get_button_position) (decor_t *d, gint *y, gint *w, gint *h); +gfloat (*theme_get_title_scale) (decor_frame_t *frame); extern char *program_name; -extern GtkWidget *style_window_rgba; -extern GtkWidget *style_window_rgb; -extern GtkWidget *switcher_label; - +/* list of all decorations */ extern GHashTable *frame_table; + +#define WINDOW_TYPE_FRAMES_NUM 4 +const gchar * window_type_frames[WINDOW_TYPE_FRAMES_NUM]; + +/* action menu */ extern GtkWidget *action_menu; extern gboolean action_menu_mapped; extern decor_color_t _title_color[2]; -extern PangoContext *pango_context; extern gint double_click_timeout; + +/* tooltip */ extern GtkWidget *tip_window; extern GtkWidget *tip_label; extern GTimeVal tooltip_last_popdown; @@ -435,37 +492,98 @@ extern gint tooltip_timer_tag; extern GSList *draw_list; extern guint draw_idle_id; -extern PangoFontDescription *titlebar_font; -extern gboolean use_system_font; -extern gint text_height; - #define BLUR_TYPE_NONE 0 #define BLUR_TYPE_TITLEBAR 1 #define BLUR_TYPE_ALL 2 -extern gint blur_type; - -extern GdkPixmap *switcher_pixmap; -extern GdkPixmap *switcher_buffer_pixmap; -extern gint switcher_width; -extern gint switcher_height; -extern Window switcher_selected_window; -extern decor_t *switcher_window; +/* switcher */ +extern Window switcher_selected_window; +extern GtkWidget *switcher_label; +extern decor_t *switcher_window; extern XRenderPictFormat *xformat_rgba; extern XRenderPictFormat *xformat_rgb; -extern Atom compiz_shadow_info_atom; -extern Atom compiz_shadow_color_atom; - /* gtk-window-decorator.c */ double dist (double x1, double y1, double x2, double y2); +/* frames.c */ + +void +initialize_decorations (); + +void +update_frames_border_extents (gpointer key, + gpointer value, + gpointer user_data); + +decor_frame_t * +gwd_get_decor_frame (const gchar *); + +decor_frame_t * +gwd_decor_frame_ref (decor_frame_t *); + +decor_frame_t * +gwd_decor_frame_unref (decor_frame_t *); + +void +gwd_frames_foreach (GHFunc foreach_func, + gpointer user_data); + +void +gwd_process_frames (GHFunc foreach_func, + const gchar *frame_keys[], + gint frame_keys_num, + gpointer user_data); + +decor_frame_t * +decor_frame_new (const gchar *type); + +void +decor_frame_destroy (decor_frame_t *); + /* decorator.c */ +void +frame_update_shadow (decor_frame_t *frame, + decor_shadow_info_t *info, + decor_shadow_options_t *opt_shadow, + decor_shadow_options_t *opt_no_shadow); + +void +frame_update_titlebar_font (decor_frame_t *frame); + +void +bare_frame_update_shadow (Display *xdisplay, + Screen *screen, + decor_frame_t *frame, + decor_shadow_info_t *info, + decor_shadow_options_t *opt_shadow, + decor_shadow_options_t *opt_no_shadow); + +void +decor_frame_update_shadow (Display *xdisplay, + Screen *screen, + decor_frame_t *frame, + decor_shadow_info_t *info, + decor_shadow_options_t *opt_shadow, + decor_shadow_options_t *opt_no_shadow); + +decor_frame_t * +create_normal_frame (const gchar *type); + +void +destroy_normal_frame (); + +decor_frame_t * +create_bare_frame (const gchar *type); + +void +destroy_bare_frame (); + gboolean update_window_decoration_size (WnckWindow *win); @@ -493,11 +611,11 @@ update_event_windows (WnckWindow *win); int update_shadow (void); -void +gboolean shadow_property_changed (WnckScreen *screen); void -update_titlebar_font (void); +update_titlebar_font (); void update_window_decoration_name (WnckWindow *win); @@ -511,10 +629,11 @@ queue_decor_draw (decor_t *d); void copy_to_front_buffer (decor_t *d); - - /* wnck.c*/ +const gchar * +get_frame_type (WnckWindowType type); + void decorations_changed (WnckScreen *screen); @@ -522,6 +641,14 @@ void connect_screen (WnckScreen *screen); void +window_opened (WnckScreen *screen, + WnckWindow *window); + +void +window_closed (WnckScreen *screen, + WnckWindow *window); + +void add_frame_window (WnckWindow *win, Window frame, Bool mode); @@ -613,7 +740,7 @@ calc_decoration_size (decor_t *d, gint *height); void -update_border_extents (gint text_height); +update_border_extents (); gboolean get_button_position (decor_t *d, @@ -636,6 +763,9 @@ get_event_window_position (decor_t *d, gint *w, gint *h); +gfloat +get_title_scale (decor_frame_t *frame); + /* gdk.c */ void @@ -653,15 +783,19 @@ XRenderPictFormat * get_format_for_drawable (decor_t *d, GdkDrawable *drawable); GdkPixmap * -create_pixmap (int w, - int h, - int depth); +create_pixmap (int w, + int h, + GtkWidget *parent_style_window); GdkPixmap * -pixmap_new_from_pixbuf (GdkPixbuf *pixbuf, int depth); +pixmap_new_from_pixbuf (GdkPixbuf *pixbuf, GtkWidget *parent); /* metacity.c */ #ifdef USE_METACITY + +MetaFrameType +meta_get_frame_type_for_decor_type (const gchar *frame_type); + void meta_draw_window_decoration (decor_t *d); @@ -671,6 +805,7 @@ meta_get_decoration_geometry (decor_t *d, MetaFrameFlags *flags, MetaFrameGeometry *fgeom, MetaButtonLayout *button_layout, + MetaFrameType frame_type, GdkRectangle *clip); void @@ -708,8 +843,12 @@ meta_get_event_window_position (decor_t *d, gint *y, gint *w, gint *h); + +gfloat +meta_get_title_scale (decor_frame_t *); + void -meta_update_border_extents (gint text_height); +meta_update_border_extents (); void meta_update_button_layout (const char *value); @@ -719,6 +858,20 @@ meta_update_button_layout (const char *value); #define SWITCHER_ALPHA 0xa0a0 void +switcher_frame_update_shadow (Display *xdisplay, + Screen *screen, + decor_frame_t *frame, + decor_shadow_info_t *info, + decor_shadow_options_t *opt_shadow, + decor_shadow_options_t *opt_no_shadow); + +decor_frame_t * +create_switcher_frame (const gchar *); + +void +destroy_switcher_frame (); + +void draw_switcher_decoration (decor_t *d); gboolean @@ -950,10 +1103,19 @@ void update_style (GtkWidget *widget); void -style_changed (GtkWidget *widget); +style_changed (GtkWidget *widget, void *user_data /* PangoContext */); /* settings.c */ +void +set_frame_scale (decor_frame_t *frame, + gchar *font_str); + +void +set_frames_scales (gpointer key, + gpointer value, + gpointer user_data); + gboolean init_settings (WnckScreen *screen); diff --git a/gtk/window-decorator/metacity.c b/gtk/window-decorator/metacity.c index 204b608..f99bf2b 100644 --- a/gtk/window-decorator/metacity.c +++ b/gtk/window-decorator/metacity.c @@ -1,15 +1,32 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + * + * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com> + * Frames Management: Copright © 2011 Canonical Ltd. + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> + */ + #include "gtk-window-decorator.h" #ifdef USE_METACITY -double meta_opacity = META_OPACITY; -gboolean meta_shade_opacity = META_SHADE_OPACITY; -double meta_active_opacity = META_ACTIVE_OPACITY; -gboolean meta_active_shade_opacity = META_ACTIVE_SHADE_OPACITY; - -gboolean meta_button_layout_set = FALSE; -MetaButtonLayout meta_button_layout; - static void decor_update_meta_window_property (decor_t *d, MetaTheme *theme, @@ -23,7 +40,8 @@ decor_update_meta_window_property (decor_t *d, Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); gint nQuad; - decor_extents_t extents, max_extents; + decor_extents_t win_extents = d->frame->win_extents; + decor_extents_t max_win_extents = d->frame->max_win_extents; decor_quad_t quads[N_QUADS_MAX]; gint w, lh, rh; gint top_stretch_offset; @@ -59,18 +77,15 @@ decor_update_meta_window_property (decor_t *d, top_stretch_offset, bottom_stretch_offset); - extents = _win_extents; - max_extents = _max_win_extents; - - extents.top += titlebar_height; - max_extents.top += max_titlebar_height; + win_extents.top += d->frame->titlebar_height; + max_win_extents.top += d->frame->max_titlebar_height; if (d->frame_window) - decor_gen_window_property (data, &extents, &max_extents, 20, 20); + decor_gen_window_property (data, &win_extents, &max_win_extents, 20, 20); else decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap), - &extents, &extents, - &max_extents, &max_extents, + &win_extents, &win_extents, + &max_win_extents, &max_win_extents, ICON_SPACE + d->button_width, 0, quads, nQuad); @@ -349,22 +364,22 @@ meta_button_state_for_button_type (decor_t *d, { switch (type) { case META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND: - type = meta_function_to_type (meta_button_layout.left_buttons[0]); + type = meta_function_to_type (settings->meta_button_layout.left_buttons[0]); break; case META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND: - type = meta_function_to_type (meta_button_layout.left_buttons[1]); + type = meta_function_to_type (settings->meta_button_layout.left_buttons[1]); break; case META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND: - type = meta_function_to_type (meta_button_layout.left_buttons[2]); + type = meta_function_to_type (settings->meta_button_layout.left_buttons[2]); break; case META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND: - type = meta_function_to_type (meta_button_layout.right_buttons[0]); + type = meta_function_to_type (settings->meta_button_layout.right_buttons[0]); break; case META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND: - type = meta_function_to_type (meta_button_layout.right_buttons[1]); + type = meta_function_to_type (settings->meta_button_layout.right_buttons[1]); break; case META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND: - type = meta_function_to_type (meta_button_layout.right_buttons[2]); + type = meta_function_to_type (settings->meta_button_layout.right_buttons[2]); default: break; } @@ -407,13 +422,17 @@ meta_get_decoration_geometry (decor_t *d, MetaFrameFlags *flags, MetaFrameGeometry *fgeom, MetaButtonLayout *button_layout, + MetaFrameType frame_type, GdkRectangle *clip) { gint left_width, right_width, top_height, bottom_height; - if (meta_button_layout_set) + if (!(frame_type < META_FRAME_TYPE_LAST)) + frame_type = META_FRAME_TYPE_NORMAL; + + if (settings->meta_button_layout_set) { - *button_layout = meta_button_layout; + *button_layout = settings->meta_button_layout; } else { @@ -483,8 +502,8 @@ meta_get_decoration_geometry (decor_t *d, #endif meta_theme_get_frame_borders (theme, - META_FRAME_TYPE_NORMAL, - text_height, + frame_type, + d->frame->text_height, *flags, &top_height, &bottom_height, @@ -503,8 +522,8 @@ meta_get_decoration_geometry (decor_t *d, clip->height = d->border_layout.left.y2 - d->border_layout.left.y1; meta_theme_calc_geometry (theme, - META_FRAME_TYPE_NORMAL, - text_height, + frame_type, + d->frame->text_height, *flags, clip->width, clip->height, @@ -522,10 +541,11 @@ meta_draw_window_decoration (decor_t *d) GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); GdkPixmap *pixmap; Picture src; - MetaButtonState button_states[META_BUTTON_TYPE_LAST]; + MetaButtonState button_states [META_BUTTON_TYPE_LAST]; MetaButtonLayout button_layout; MetaFrameGeometry fgeom; MetaFrameFlags flags; + MetaFrameType frame_type; MetaTheme *theme; GtkStyle *style; cairo_t *cr; @@ -536,9 +556,9 @@ meta_draw_window_decoration (decor_t *d) Region bottom_region = NULL; Region left_region = NULL; Region right_region = NULL; - double alpha = (d->active) ? meta_active_opacity : meta_opacity; - gboolean shade_alpha = (d->active) ? meta_active_shade_opacity : - meta_shade_opacity; + double alpha = (d->active) ? settings->meta_active_opacity : settings->meta_opacity; + gboolean shade_alpha = (d->active) ? settings->meta_active_shade_opacity : + settings->meta_shade_opacity; MetaFrameStyle *frame_style; GtkWidget *style_window; GdkColor bg_color; @@ -556,18 +576,18 @@ meta_draw_window_decoration (decor_t *d) gdk_drawable_set_colormap (GDK_DRAWABLE (d->buffer_pixmap), cmap); } - if (decoration_alpha == 1.0) + if (settings->decoration_alpha == 1.0) alpha = 1.0; if (gdk_drawable_get_depth (GDK_DRAWABLE (d->pixmap)) == 32) { - style = gtk_widget_get_style (style_window_rgba); - style_window = style_window_rgba; + style = gtk_widget_get_style (d->frame->style_window_rgba); + style_window = d->frame->style_window_rgba; } else { - style = gtk_widget_get_style (style_window_rgb); - style_window = style_window_rgb; + style = gtk_widget_get_style (d->frame->style_window_rgb); + style_window = d->frame->style_window_rgb; } drawable = d->buffer_pixmap ? d->buffer_pixmap : d->pixmap; @@ -578,8 +598,13 @@ meta_draw_window_decoration (decor_t *d) theme = meta_theme_get_current (); + frame_type = meta_frame_type_from_string (d->frame->type); + + if (frame_type == META_FRAME_TYPE_LAST) + frame_type = META_FRAME_TYPE_NORMAL; + meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout, - &clip); + frame_type, &clip); /* we only have to redraw the shadow background when decoration changed size */ @@ -590,7 +615,7 @@ meta_draw_window_decoration (decor_t *d) button_states[i] = meta_button_state_for_button_type (d, i); frame_style = meta_theme_get_frame_style (theme, - META_FRAME_TYPE_NORMAL, + frame_type, flags); bg_color = style->bg[GTK_STATE_NORMAL]; @@ -626,11 +651,11 @@ meta_draw_window_decoration (decor_t *d) cmap = get_colormap_for_drawable (GDK_DRAWABLE (d->pixmap)); depth = gdk_drawable_get_depth (GDK_DRAWABLE (d->frame_window)); - pixmap = create_pixmap (rect.width, size, depth); + pixmap = create_pixmap (rect.width, size, d->frame->style_window_rgb); gdk_drawable_set_colormap (GDK_DRAWABLE (pixmap), cmap); } else - pixmap = create_pixmap (rect.width, size, 32); + pixmap = create_pixmap (rect.width, size, d->frame->style_window_rgba); cr = gdk_cairo_create (GDK_DRAWABLE (pixmap)); gdk_cairo_set_source_color_alpha (cr, &bg_color, bg_alpha); @@ -651,14 +676,14 @@ meta_draw_window_decoration (decor_t *d) pixmap, &rect, 0, 0, - META_FRAME_TYPE_NORMAL, + frame_type, flags, clip.width - fgeom.left_width - fgeom.right_width, clip.height - fgeom.top_height - fgeom.bottom_height, d->layout, - text_height, + d->frame->text_height, &button_layout, button_states, d->icon_pixbuf, @@ -691,14 +716,14 @@ meta_draw_window_decoration (decor_t *d) &rect, 0, -(clip.height - fgeom.bottom_height), - META_FRAME_TYPE_NORMAL, + frame_type, flags, clip.width - fgeom.left_width - fgeom.right_width, clip.height - fgeom.top_height - fgeom.bottom_height, d->layout, - text_height, + d->frame->text_height, &button_layout, button_states, d->icon_pixbuf, @@ -742,11 +767,11 @@ meta_draw_window_decoration (decor_t *d) cmap = get_colormap_for_drawable (GDK_DRAWABLE (d->pixmap)); depth = gdk_drawable_get_depth (GDK_DRAWABLE (d->frame_window)); - pixmap = create_pixmap (size, rect.height, depth); + pixmap = create_pixmap (size, rect.height, d->frame->style_window_rgb); gdk_drawable_set_colormap (GDK_DRAWABLE (pixmap), cmap); } else - pixmap = create_pixmap (size, rect.height, 32); + pixmap = create_pixmap (size, rect.height, d->frame->style_window_rgba); cr = gdk_cairo_create (GDK_DRAWABLE (pixmap)); gdk_cairo_set_source_color_alpha (cr, &bg_color, bg_alpha); @@ -768,14 +793,14 @@ meta_draw_window_decoration (decor_t *d) &rect, 0, -fgeom.top_height, - META_FRAME_TYPE_NORMAL, + frame_type, flags, clip.width - fgeom.left_width - fgeom.right_width, clip.height - fgeom.top_height - fgeom.bottom_height, d->layout, - text_height, + d->frame->text_height, &button_layout, button_states, d->icon_pixbuf, @@ -808,14 +833,14 @@ meta_draw_window_decoration (decor_t *d) &rect, -(clip.width - fgeom.right_width), -fgeom.top_height, - META_FRAME_TYPE_NORMAL, + frame_type, flags, clip.width - fgeom.left_width - fgeom.right_width, clip.height - fgeom.top_height - fgeom.bottom_height, d->layout, - text_height, + d->frame->text_height, &button_layout, button_states, d->icon_pixbuf, @@ -848,20 +873,6 @@ meta_draw_window_decoration (decor_t *d) if (d->frame_window) { GdkWindow *gdk_frame_window = gtk_widget_get_window (d->decor_window); - decor_extents_t extents; - - if (d->state & (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY | - WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)) - { - extents.left = 0; - extents.right = 0; - extents.top = 10; - extents.bottom = 0; - } - else - { - extents = _win_extents; - } /* * FIXME: What is '4' supposed to be for here... @@ -935,14 +946,14 @@ meta_calc_button_size (decor_t *d) } gboolean -meta_get_button_position (decor_t *d, - gint i, - gint width, - gint height, - gint *x, - gint *y, - gint *w, - gint *h) +meta_get_button_position (decor_t *d, + gint i, + gint width, + gint height, + gint *x, + gint *y, + gint *w, + gint *h) { MetaButtonLayout button_layout; MetaFrameGeometry fgeom; @@ -965,6 +976,7 @@ meta_get_button_position (decor_t *d, theme = meta_theme_get_current (); meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout, + meta_frame_type_from_string (d->frame->type), &clip); switch (i) { @@ -1058,13 +1070,30 @@ meta_get_button_position (decor_t *d, if (d->frame_window) { - *x += _win_extents.left + 4; - *y += _win_extents.top + 2; + *x += d->frame->win_extents.left + 4; + *y += d->frame->win_extents.top + 2; } return TRUE; } +gfloat +meta_get_title_scale (decor_frame_t *frame) +{ + MetaTheme *theme = meta_theme_get_current (); + MetaFrameType type; + MetaFrameFlags flags = 0xc33; /* fixme */ + + type = meta_frame_type_from_string (frame->type); + + if (type == META_FRAME_TYPE_LAST) + return 1.0f; + + gfloat scale = meta_theme_get_title_scale (theme, type, flags); + + return scale; +} + gboolean meta_calc_decoration_size (decor_t *d, gint w, @@ -1081,26 +1110,26 @@ meta_calc_decoration_size (decor_t *d, { if (!d->frame_window) { - context = &max_window_context; - shadow = max_border_shadow; + context = &d->frame->max_window_context; + shadow = d->frame->max_border_shadow; } else { - context = &max_window_context_no_shadow; - shadow = max_border_no_shadow; + context = &d->frame->max_window_context_no_shadow; + shadow = d->frame->max_border_no_shadow; } } else { if (!d->frame_window) { - context = &window_context; - shadow = border_shadow; + context = &d->frame->window_context; + shadow = d->frame->border_shadow; } else { - context = &window_context_no_shadow; - shadow = border_no_shadow; + context = &d->frame->window_context_no_shadow; + shadow = d->frame->border_no_shadow; } } @@ -1127,7 +1156,7 @@ meta_calc_decoration_size (decor_t *d, { if ((d->state & META_MAXIMIZED) == META_MAXIMIZED) decor_get_default_layout (context, d->client_width, - d->client_height - titlebar_height, + d->client_height - d->frame->titlebar_height, &layout); else decor_get_default_layout (context, d->client_width, @@ -1137,7 +1166,7 @@ meta_calc_decoration_size (decor_t *d, *height = layout.height; d->border_layout = layout; - d->shadow = no_border_shadow; + d->shadow = shadow; d->context = context; meta_calc_button_size (d); @@ -1183,11 +1212,14 @@ meta_get_event_window_position (decor_t *d, MetaFrameGeometry fgeom; MetaFrameFlags flags; MetaTheme *theme; + WnckWindowType win_type; GdkRectangle clip; theme = meta_theme_get_current (); + win_type = wnck_window_get_window_type (d->win); meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout, + meta_frame_type_from_string (d->frame->type), &clip); width += fgeom.right_width + fgeom.left_width; @@ -1200,9 +1232,9 @@ meta_get_event_window_position (decor_t *d, if (d->frame_window) { *x = width - fgeom.right_width - RESIZE_EXTENDS + - _win_extents.left + 2; + d->frame->win_extents.left + 2; *y = height - fgeom.bottom_height - RESIZE_EXTENDS + - _win_extents.top + 2; + d->frame->win_extents.top + 2; } else { @@ -1216,7 +1248,7 @@ meta_get_event_window_position (decor_t *d, *x = fgeom.left_width + RESIZE_EXTENDS; *y = height - fgeom.bottom_height; if (d->frame_window) - *y += _win_extents.top + 2; + *y += d->frame->win_extents.top + 2; *w = width - fgeom.left_width - fgeom.right_width - (2 * RESIZE_EXTENDS); *h = fgeom.bottom_height; @@ -1227,8 +1259,8 @@ meta_get_event_window_position (decor_t *d, *y = height - fgeom.bottom_height - RESIZE_EXTENDS; if (d->frame_window) { - *x += _win_extents.left + 4; - *y += _win_extents.bottom + 2; + *x += d->frame->win_extents.left + 4; + *y += d->frame->win_extents.bottom + 2; } *w = fgeom.left_width + RESIZE_EXTENDS; *h = fgeom.bottom_height + RESIZE_EXTENDS; @@ -1240,7 +1272,7 @@ meta_get_event_window_position (decor_t *d, case 2: /* right */ *x = width - fgeom.right_width; if (d->frame_window) - *x += _win_extents.left + 2; + *x += d->frame->win_extents.left + 2; *w = fgeom.right_width; *h = height - fgeom.top_height - fgeom.bottom_height - (2 * RESIZE_EXTENDS); @@ -1255,7 +1287,7 @@ meta_get_event_window_position (decor_t *d, default: *x = 0; if (d->frame_window) - *x += _win_extents.left + 4; + *x += d->frame->win_extents.left + 4; *y = fgeom.top_height + RESIZE_EXTENDS; *w = fgeom.left_width; *h = height - fgeom.top_height - fgeom.bottom_height - @@ -1271,8 +1303,8 @@ meta_get_event_window_position (decor_t *d, *y = 0; if (d->frame_window) { - *x += _win_extents.left + 2; - *y += _win_extents.top + 2 - fgeom.title_rect.height; + *x += d->frame->win_extents.left + 2; + *y += d->frame->win_extents.top + 2 - fgeom.title_rect.height; } *w = fgeom.right_width + RESIZE_EXTENDS; *h = fgeom.top_height + RESIZE_EXTENDS; @@ -1281,7 +1313,7 @@ meta_get_event_window_position (decor_t *d, *x = fgeom.left_width + RESIZE_EXTENDS; *y = 0; if (d->frame_window) - *y += _win_extents.top + 2; + *y += d->frame->win_extents.top + 2; *w = width - fgeom.left_width - fgeom.right_width - (2 * RESIZE_EXTENDS); *h = fgeom.title_rect.y + TOP_RESIZE_HEIGHT; @@ -1292,8 +1324,8 @@ meta_get_event_window_position (decor_t *d, *y = 0; if (d->frame_window) { - *x += _win_extents.left + 4; - *y += _win_extents.top + 2 - fgeom.title_rect.height; + *x += d->frame->win_extents.left + 4; + *y += d->frame->win_extents.top + 2 - fgeom.title_rect.height; } *w = fgeom.left_width + RESIZE_EXTENDS; *h = fgeom.top_height + RESIZE_EXTENDS; @@ -1547,46 +1579,56 @@ meta_update_button_layout (const char *value) new_layout = rtl_layout; } - meta_button_layout = new_layout; + settings->meta_button_layout = new_layout; } void -meta_update_border_extents (gint text_height) +meta_update_border_extents (decor_frame_t *frame) { - MetaTheme *theme; - gint top_height, bottom_height, left_width, right_width; + MetaTheme *theme = meta_theme_get_current (); - theme = meta_theme_get_current (); + gwd_decor_frame_ref (frame); + decor_frame_t *default_frame = gwd_get_decor_frame ("default"); + MetaFrameType frame_type = meta_frame_type_from_string (frame->type); + gint top_height, bottom_height, left_width, right_width; + + if (!(frame_type < META_FRAME_TYPE_LAST)) + frame_type = META_FRAME_TYPE_NORMAL; meta_theme_get_frame_borders (theme, - META_FRAME_TYPE_NORMAL, - text_height, 0, + frame_type, + frame->text_height, + 0, &top_height, &bottom_height, &left_width, &right_width); - _win_extents.top = _default_win_extents.top; - _win_extents.bottom = bottom_height; - _win_extents.left = left_width; - _win_extents.right = right_width; + frame->win_extents.top = default_frame->win_extents.top; + frame->win_extents.bottom = bottom_height; + frame->win_extents.left = left_width; + frame->win_extents.right = right_width; - titlebar_height = top_height - _win_extents.top; + frame->titlebar_height = top_height - frame->win_extents.top; meta_theme_get_frame_borders (theme, - META_FRAME_TYPE_NORMAL, - text_height, META_FRAME_MAXIMIZED, + frame_type, + frame->text_height, + META_FRAME_MAXIMIZED, &top_height, &bottom_height, &left_width, &right_width); - _max_win_extents.top = _default_win_extents.top; - _max_win_extents.bottom = bottom_height; - _max_win_extents.left = left_width; - _max_win_extents.right = right_width; + frame->max_win_extents.top = default_frame->win_extents.top; + frame->max_win_extents.bottom = bottom_height; + frame->max_win_extents.left = left_width; + frame->max_win_extents.right = right_width; + + frame->max_titlebar_height = top_height - frame->max_win_extents.top; - max_titlebar_height = top_height - _max_win_extents.top; + gwd_decor_frame_unref (frame); + gwd_decor_frame_unref (default_frame); } #endif diff --git a/gtk/window-decorator/settings.c b/gtk/window-decorator/settings.c index 31cc3e9..0ceea0b 100644 --- a/gtk/window-decorator/settings.c +++ b/gtk/window-decorator/settings.c @@ -1,10 +1,31 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + */ + #include "gtk-window-decorator.h" /* TODO: Trash all of this and use a window property * instead - much much cleaner! */ -void +gboolean shadow_property_changed (WnckScreen *s) { GdkDisplay *display = gdk_display_get_default (); @@ -23,7 +44,7 @@ shadow_property_changed (WnckScreen *s) &format, &n, &left, &prop_data); if (result != Success) - return; + return FALSE; if (n == 4) { @@ -39,15 +60,15 @@ shadow_property_changed (WnckScreen *s) radius /= 1000; opacity /= 1000; - changed = radius != shadow_radius || - opacity != shadow_opacity || - x_off != shadow_offset_x || - y_off != shadow_offset_y; + changed = radius != settings->shadow_radius || + opacity != settings->shadow_opacity || + x_off != settings->shadow_offset_x || + y_off != settings->shadow_offset_y; - shadow_radius = (gdouble) MAX (0.0, MIN (radius, 48.0)); - shadow_opacity = (gdouble) MAX (0.0, MIN (opacity, 6.0)); - shadow_offset_x = (gint) MAX (-16, MIN (x_off, 16)); - shadow_offset_y = (gint) MAX (-16, MIN (y_off, 16)); + settings->shadow_radius = (gdouble) MAX (0.0, MIN (radius, 48.0)); + settings->shadow_opacity = (gdouble) MAX (0.0, MIN (opacity, 6.0)); + settings->shadow_offset_x = (gint) MAX (-16, MIN (x_off, 16)); + settings->shadow_offset_y = (gint) MAX (-16, MIN (y_off, 16)); } XFree (prop_data); @@ -69,9 +90,9 @@ shadow_property_changed (WnckScreen *s) if (sscanf (t_data[0], "#%2x%2x%2x%2x", &c[0], &c[1], &c[2], &c[3]) == 4) { - shadow_color[0] = c[0] << 8 | c[0]; - shadow_color[1] = c[1] << 8 | c[1]; - shadow_color[2] = c[2] << 8 | c[2]; + settings->shadow_color[0] = c[0] << 8 | c[0]; + settings->shadow_color[1] = c[1] << 8 | c[1]; + settings->shadow_color[2] = c[2] << 8 | c[2]; changed = TRUE; } } @@ -81,8 +102,7 @@ shadow_property_changed (WnckScreen *s) XFreeStringList (t_data); } - if (changed) - decorations_changed (s); + return changed; } #ifdef USE_GCONF @@ -90,7 +110,7 @@ static gboolean blur_settings_changed (GConfClient *client) { gchar *type; - int new_type = blur_type; + int new_type = settings->blur_type; if (cmdline_options & CMDLINE_BLUR) return FALSE; @@ -111,9 +131,9 @@ blur_settings_changed (GConfClient *client) g_free (type); } - if (new_type != blur_type) + if (new_type != settings->blur_type) { - blur_type = new_type; + settings->blur_type = new_type; return TRUE; } @@ -163,6 +183,7 @@ theme_changed (GConfClient *client) theme_update_border_extents = meta_update_border_extents; theme_get_event_window_position = meta_get_event_window_position; theme_get_button_position = meta_get_button_position; + theme_get_title_scale = meta_get_title_scale; } else { @@ -171,6 +192,7 @@ theme_changed (GConfClient *client) theme_update_border_extents = update_border_extents; theme_get_event_window_position = get_event_window_position; theme_get_button_position = get_button_position; + theme_get_title_scale = get_title_scale; } return TRUE; @@ -180,6 +202,7 @@ theme_changed (GConfClient *client) theme_update_border_extents = update_border_extents; theme_get_event_window_position = get_event_window_position; theme_get_button_position = get_button_position; + theme_get_title_scale = get_title_scale; return FALSE; #endif @@ -199,9 +222,9 @@ theme_opacity_changed (GConfClient *client) NULL); if (!(cmdline_options & CMDLINE_OPACITY) && - opacity != meta_opacity) + opacity != settings->meta_opacity) { - meta_opacity = opacity; + settings->meta_opacity = opacity; changed = TRUE; } @@ -212,9 +235,9 @@ theme_opacity_changed (GConfClient *client) NULL); if (!(cmdline_options & CMDLINE_OPACITY_SHADE) && - shade_opacity != meta_shade_opacity) + shade_opacity != settings->meta_shade_opacity) { - meta_shade_opacity = shade_opacity; + settings->meta_shade_opacity = shade_opacity; changed = TRUE; } } @@ -224,9 +247,9 @@ theme_opacity_changed (GConfClient *client) NULL); if (!(cmdline_options & CMDLINE_ACTIVE_OPACITY) && - opacity != meta_active_opacity) + opacity != settings->meta_active_opacity) { - meta_active_opacity = opacity; + settings->meta_active_opacity = opacity; changed = TRUE; } @@ -238,9 +261,9 @@ theme_opacity_changed (GConfClient *client) NULL); if (!(cmdline_options & CMDLINE_ACTIVE_OPACITY_SHADE) && - shade_opacity != meta_active_shade_opacity) + shade_opacity != settings->meta_active_shade_opacity) { - meta_active_shade_opacity = shade_opacity; + settings->meta_active_shade_opacity = shade_opacity; changed = TRUE; } } @@ -267,16 +290,16 @@ button_layout_changed (GConfClient *client) { meta_update_button_layout (button_layout); - meta_button_layout_set = TRUE; + settings->meta_button_layout_set = TRUE; g_free (button_layout); return TRUE; } - if (meta_button_layout_set) + if (settings->meta_button_layout_set) { - meta_button_layout_set = FALSE; + settings->meta_button_layout_set = FALSE; return TRUE; } #endif @@ -284,6 +307,42 @@ button_layout_changed (GConfClient *client) return FALSE; } +void +set_frame_scale (decor_frame_t *frame, + gchar *font_str) +{ + gfloat scale = 1.0f; + + gwd_decor_frame_ref (frame); + + if (frame->titlebar_font) + pango_font_description_free (frame->titlebar_font); + + frame->titlebar_font = pango_font_description_from_string (font_str); + + scale = (*theme_get_title_scale) (frame); + + pango_font_description_set_size (frame->titlebar_font, + MAX (pango_font_description_get_size (frame->titlebar_font) * scale, 1)); + + gwd_decor_frame_unref (frame); +} + +void +set_frames_scales (gpointer key, + gpointer value, + gpointer user_data) +{ + decor_frame_t *frame = (decor_frame_t *) value; + gchar *font_str = (gchar *) user_data; + + gwd_decor_frame_ref (frame); + + set_frame_scale (frame, font_str); + + gwd_decor_frame_unref (frame); +} + static void titlebar_font_changed (GConfClient *client) { @@ -295,12 +354,16 @@ titlebar_font_changed (GConfClient *client) if (!str) str = g_strdup ("Sans Bold 12"); - if (titlebar_font) - pango_font_description_free (titlebar_font); + if (settings->font) + { + g_free (settings->font); + settings->font = g_strdup (str); + } - titlebar_font = pango_font_description_from_string (str); + gwd_frames_foreach (set_frames_scales, (gpointer) settings->font); - g_free (str); + if (str) + g_free (str); } static void @@ -340,15 +403,15 @@ wheel_action_changed (GConfClient *client) { gchar *action; - wheel_action = WHEEL_ACTION_DEFAULT; + settings->wheel_action = WHEEL_ACTION_DEFAULT; action = gconf_client_get_string (client, WHEEL_ACTION_KEY, NULL); if (action) { if (strcmp (action, "shade") == 0) - wheel_action = WHEEL_ACTION_SHADE; + settings->wheel_action = WHEEL_ACTION_SHADE; else if (strcmp (action, "none") == 0) - wheel_action = WHEEL_ACTION_NONE; + settings->wheel_action = WHEEL_ACTION_NONE; g_free (action); } @@ -366,33 +429,33 @@ value_changed (GConfClient *client, { if (gconf_client_get_bool (client, COMPIZ_USE_SYSTEM_FONT_KEY, - NULL) != use_system_font) + NULL) != settings->use_system_font) { - use_system_font = !use_system_font; + settings->use_system_font = !settings->use_system_font; changed = TRUE; } } else if (strcmp (key, COMPIZ_TITLEBAR_FONT_KEY) == 0) { titlebar_font_changed (client); - changed = !use_system_font; + changed = !settings->use_system_font; } else if (strcmp (key, COMPIZ_DOUBLE_CLICK_TITLEBAR_KEY) == 0) { titlebar_click_action_changed (client, key, - &double_click_action, + &settings->double_click_action, DOUBLE_CLICK_ACTION_DEFAULT); } else if (strcmp (key, COMPIZ_MIDDLE_CLICK_TITLEBAR_KEY) == 0) { titlebar_click_action_changed (client, key, - &middle_click_action, + &settings->middle_click_action, MIDDLE_CLICK_ACTION_DEFAULT); } else if (strcmp (key, COMPIZ_RIGHT_CLICK_TITLEBAR_KEY) == 0) { titlebar_click_action_changed (client, key, - &right_click_action, + &settings->right_click_action, RIGHT_CLICK_ACTION_DEFAULT); } else if (strcmp (key, WHEEL_ACTION_KEY) == 0) @@ -432,11 +495,6 @@ value_changed (GConfClient *client, gboolean init_settings (WnckScreen *screen) { - GtkSettings *settings; - GdkScreen *gdkscreen; - GdkColormap *colormap; - AtkObject *switcher_label_obj; - #ifdef USE_GCONF GConfClient *gconf; @@ -456,105 +514,33 @@ init_settings (WnckScreen *screen) "value_changed", G_CALLBACK (value_changed), screen); -#endif - - style_window_rgba = gtk_window_new (GTK_WINDOW_POPUP); - - gdkscreen = gdk_display_get_default_screen (gdk_display_get_default ()); - colormap = gdk_screen_get_rgba_colormap (gdkscreen); - if (colormap) - gtk_widget_set_colormap (style_window_rgba, colormap); - - gtk_widget_realize (style_window_rgba); - - switcher_label = gtk_label_new (""); - switcher_label_obj = gtk_widget_get_accessible (switcher_label); - atk_object_set_role (switcher_label_obj, ATK_ROLE_STATUSBAR); - gtk_container_add (GTK_CONTAINER (style_window_rgba), switcher_label); - - gtk_widget_set_size_request (style_window_rgba, 0, 0); - gtk_window_move (GTK_WINDOW (style_window_rgba), -100, -100); - gtk_widget_show_all (style_window_rgba); - - g_signal_connect_object (style_window_rgba, "style-set", - G_CALLBACK (style_changed), - 0, 0); - - settings = gtk_widget_get_settings (style_window_rgba); - - g_object_get (G_OBJECT (settings), "gtk-double-click-time", - &double_click_timeout, NULL); - - pango_context = gtk_widget_create_pango_context (style_window_rgba); - - style_window_rgb = gtk_window_new (GTK_WINDOW_POPUP); - - gdkscreen = gdk_display_get_default_screen (gdk_display_get_default ()); - colormap = gdk_screen_get_rgb_colormap (gdkscreen); - if (colormap) - gtk_widget_set_colormap (style_window_rgb, colormap); - - gtk_widget_realize (style_window_rgb); - - switcher_label = gtk_label_new (""); - switcher_label_obj = gtk_widget_get_accessible (switcher_label); - atk_object_set_role (switcher_label_obj, ATK_ROLE_STATUSBAR); - gtk_container_add (GTK_CONTAINER (style_window_rgb), switcher_label); - - gtk_widget_set_size_request (style_window_rgb, 0, 0); - gtk_window_move (GTK_WINDOW (style_window_rgb), -100, -100); - gtk_widget_show_all (style_window_rgb); - - g_signal_connect_object (style_window_rgb, "style-set", - G_CALLBACK (style_changed), - 0, 0); - - settings = gtk_widget_get_settings (style_window_rgb); - - g_object_get (G_OBJECT (settings), "gtk-double-click-time", - &double_click_timeout, NULL); - - pango_context = gtk_widget_create_pango_context (style_window_rgb); - -#ifdef USE_GCONF - use_system_font = gconf_client_get_bool (gconf, - COMPIZ_USE_SYSTEM_FONT_KEY, - NULL); + settings->use_system_font = gconf_client_get_bool (gconf, + COMPIZ_USE_SYSTEM_FONT_KEY, + NULL); theme_changed (gconf); theme_opacity_changed (gconf); button_layout_changed (gconf); -#endif - - update_style (style_window_rgba); - update_style (style_window_rgb); -#ifdef USE_GCONF titlebar_font_changed (gconf); -#endif - update_titlebar_font (); - -#ifdef USE_GCONF titlebar_click_action_changed (gconf, COMPIZ_DOUBLE_CLICK_TITLEBAR_KEY, - &double_click_action, + &settings->double_click_action, DOUBLE_CLICK_ACTION_DEFAULT); titlebar_click_action_changed (gconf, COMPIZ_MIDDLE_CLICK_TITLEBAR_KEY, - &middle_click_action, + &settings->middle_click_action, MIDDLE_CLICK_ACTION_DEFAULT); titlebar_click_action_changed (gconf, COMPIZ_RIGHT_CLICK_TITLEBAR_KEY, - &right_click_action, + &settings->right_click_action, RIGHT_CLICK_ACTION_DEFAULT); wheel_action_changed (gconf); blur_settings_changed (gconf); -#endif - (*theme_update_border_extents) (text_height); + g_object_unref (gconf); +#endif shadow_property_changed (screen); - update_shadow (); - return TRUE; } diff --git a/gtk/window-decorator/style.c b/gtk/window-decorator/style.c index 5090ff6..f3d9d50 100644 --- a/gtk/window-decorator/style.c +++ b/gtk/window-decorator/style.c @@ -1,3 +1,24 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + */ + #include "gtk-window-decorator.h" void @@ -23,19 +44,22 @@ update_style (GtkWidget *widget) } void -style_changed (GtkWidget *widget) +style_changed (GtkWidget *widget, + void *user_data) { GdkDisplay *gdkdisplay; GdkScreen *gdkscreen; WnckScreen *screen; + PangoContext *context = (PangoContext *) user_data; + gdkdisplay = gdk_display_get_default (); gdkscreen = gdk_display_get_default_screen (gdkdisplay); screen = wnck_screen_get_default (); update_style (widget); - pango_cairo_context_set_resolution (pango_context, + pango_cairo_context_set_resolution (context, gdk_screen_get_resolution (gdkscreen)); decorations_changed (screen); diff --git a/gtk/window-decorator/switcher.c b/gtk/window-decorator/switcher.c index 6da0475..1aec3b1 100644 --- a/gtk/window-decorator/switcher.c +++ b/gtk/window-decorator/switcher.c @@ -1,5 +1,72 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + * + * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com> + * Frames Management: Copright © 2011 Canonical Ltd. + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> + */ + #include "gtk-window-decorator.h" +decor_frame_t * +create_switcher_frame (const gchar *type) +{ + AtkObject *switcher_label_obj; + decor_frame_t *frame = decor_frame_new (type); + decor_extents_t _switcher_extents = { 6, 6, 6, 6 + SWITCHER_SPACE }; + + decor_context_t _switcher_context = { + { 0, 0, 0, 0 }, + 6, 6, 6, 6 + SWITCHER_SPACE, + 0, 0, 0, 0 + }; + + frame->win_extents = _switcher_extents; + frame->max_win_extents = _switcher_extents; + frame->win_extents = _switcher_extents; + frame->window_context = _switcher_context; + frame->window_context_no_shadow = _switcher_context; + frame->max_window_context = _switcher_context; + frame->max_window_context_no_shadow = _switcher_context; + frame->update_shadow = switcher_frame_update_shadow; + + /* keep the switcher frame around since we need to keep its + * contents */ + + gwd_decor_frame_ref (frame); + + switcher_label = gtk_label_new (""); + switcher_label_obj = gtk_widget_get_accessible (switcher_label); + atk_object_set_role (switcher_label_obj, ATK_ROLE_STATUSBAR); + gtk_container_add (GTK_CONTAINER (frame->style_window_rgba), switcher_label); + + return frame; +} + +void +destroy_switcher_frame (decor_frame_t *frame) +{ + gtk_widget_destroy (switcher_label); + decor_frame_destroy (frame); +} + static void draw_switcher_background (decor_t *d) { @@ -16,7 +83,7 @@ draw_switcher_background (decor_t *d) if (!d->buffer_pixmap) return; - style = gtk_widget_get_style (style_window_rgba); + style = gtk_widget_get_style (d->frame->style_window_rgba); color.r = style->bg[GTK_STATE_NORMAL].red / 65535.0; color.g = style->bg[GTK_STATE_NORMAL].green / 65535.0; @@ -26,44 +93,44 @@ draw_switcher_background (decor_t *d) cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - top = _switcher_extents.top; + top = d->frame->win_extents.top; - x1 = switcher_context.left_space - _switcher_extents.left; - y1 = switcher_context.top_space - _switcher_extents.top; - x2 = d->width - switcher_context.right_space + _switcher_extents.right; - y2 = d->height - switcher_context.bottom_space + _switcher_extents.bottom; + x1 = d->frame->window_context.left_space - d->frame->win_extents.left; + y1 = d->frame->window_context.top_space - d->frame->win_extents.top; + x2 = d->width - d->frame->window_context.right_space + d->frame->win_extents.right; + y2 = d->height - d->frame->window_context.bottom_space + d->frame->win_extents.bottom; - h = y2 - y1 - _switcher_extents.top - _switcher_extents.top; + h = y2 - y1 - d->frame->win_extents.top - d->frame->win_extents.top; cairo_set_line_width (cr, 1.0); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - draw_shadow_background (d, cr, switcher_shadow, &switcher_context); + draw_shadow_background (d, cr, d->frame->border_shadow, &d->frame->window_context); fill_rounded_rectangle (cr, x1 + 0.5, y1 + 0.5, - _switcher_extents.left - 0.5, + d->frame->win_extents.left - 0.5, top - 0.5, 5.0, CORNER_TOPLEFT, &color, alpha, &color, alpha * 0.75, SHADE_TOP | SHADE_LEFT); fill_rounded_rectangle (cr, - x1 + _switcher_extents.left, + x1 + d->frame->win_extents.left, y1 + 0.5, - x2 - x1 - _switcher_extents.left - - _switcher_extents.right, + x2 - x1 - d->frame->win_extents.left - + d->frame->win_extents.right, top - 0.5, 5.0, 0, &color, alpha, &color, alpha * 0.75, SHADE_TOP); fill_rounded_rectangle (cr, - x2 - _switcher_extents.right, + x2 - d->frame->win_extents.right, y1 + 0.5, - _switcher_extents.right - 0.5, + d->frame->win_extents.right - 0.5, top - 0.5, 5.0, CORNER_TOPRIGHT, &color, alpha, &color, alpha * 0.75, @@ -72,16 +139,16 @@ draw_switcher_background (decor_t *d) fill_rounded_rectangle (cr, x1 + 0.5, y1 + top, - _switcher_extents.left - 0.5, + d->frame->win_extents.left - 0.5, h, 5.0, 0, &color, alpha, &color, alpha * 0.75, SHADE_LEFT); fill_rounded_rectangle (cr, - x2 - _switcher_extents.right, + x2 - d->frame->win_extents.right, y1 + top, - _switcher_extents.right - 0.5, + d->frame->win_extents.right - 0.5, h, 5.0, 0, &color, alpha, &color, alpha * 0.75, @@ -89,35 +156,35 @@ draw_switcher_background (decor_t *d) fill_rounded_rectangle (cr, x1 + 0.5, - y2 - _switcher_extents.top, - _switcher_extents.left - 0.5, - _switcher_extents.top - 0.5, + y2 - d->frame->win_extents.top, + d->frame->win_extents.left - 0.5, + d->frame->win_extents.top - 0.5, 5.0, CORNER_BOTTOMLEFT, &color, alpha, &color, alpha * 0.75, SHADE_BOTTOM | SHADE_LEFT); fill_rounded_rectangle (cr, - x1 + _switcher_extents.left, - y2 - _switcher_extents.top, - x2 - x1 - _switcher_extents.left - - _switcher_extents.right, - _switcher_extents.top - 0.5, + x1 + d->frame->win_extents.left, + y2 - d->frame->win_extents.top, + x2 - x1 - d->frame->win_extents.left - + d->frame->win_extents.right, + d->frame->win_extents.top - 0.5, 5.0, 0, &color, alpha, &color, alpha * 0.75, SHADE_BOTTOM); fill_rounded_rectangle (cr, - x2 - _switcher_extents.right, - y2 - _switcher_extents.top, - _switcher_extents.right - 0.5, - _switcher_extents.top - 0.5, + x2 - d->frame->win_extents.right, + y2 - d->frame->win_extents.top, + d->frame->win_extents.right - 0.5, + d->frame->win_extents.top - 0.5, 5.0, CORNER_BOTTOMRIGHT, &color, alpha, &color, alpha * 0.75, SHADE_BOTTOM | SHADE_RIGHT); - cairo_rectangle (cr, x1 + _switcher_extents.left, + cairo_rectangle (cr, x1 + d->frame->win_extents.left, y1 + top, - x2 - x1 - _switcher_extents.left - _switcher_extents.right, + x2 - x1 - d->frame->win_extents.left - d->frame->win_extents.right, h); gdk_cairo_set_source_color_alpha (cr, &style->bg[GTK_STATE_NORMAL], @@ -207,16 +274,16 @@ draw_switcher_foreground (decor_t *d) if (!d->pixmap || !d->buffer_pixmap) return; - style = gtk_widget_get_style (style_window_rgba); + style = gtk_widget_get_style (d->frame->style_window_rgba); cr = gdk_cairo_create (GDK_DRAWABLE (d->buffer_pixmap)); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - cairo_rectangle (cr, switcher_context.left_space, - d->height - switcher_context.bottom_space, - d->width - switcher_context.left_space - - switcher_context.right_space, + cairo_rectangle (cr, d->frame->window_context.left_space, + d->height - d->frame->window_context.bottom_space, + d->width - d->frame->window_context.left_space - + d->frame->window_context.right_space, SWITCHER_SPACE); gdk_cairo_set_source_color_alpha (cr, @@ -237,8 +304,8 @@ draw_switcher_foreground (decor_t *d) pango_layout_get_pixel_size (d->layout, &w, NULL); cairo_move_to (cr, d->width / 2 - w / 2, - d->height - switcher_context.bottom_space + - SWITCHER_SPACE / 2 - text_height / 2); + d->height - d->frame->window_context.bottom_space + + SWITCHER_SPACE / 2 - d->frame->text_height / 2); pango_cairo_show_layout (cr, d->layout); } @@ -260,6 +327,28 @@ draw_switcher_decoration (decor_t *d) void switcher_window_closed () { + decor_t *d = switcher_window; + Display *xdisplay = gdk_x11_get_default_xdisplay (); + + if (d->layout) + g_object_unref (G_OBJECT (d->layout)); + + if (d->name) + g_free (d->name); + + if (d->pixmap) + g_object_unref (G_OBJECT (d->pixmap)); + + if (d->buffer_pixmap) + g_object_unref (G_OBJECT (d->buffer_pixmap)); + + if (d->cr) + cairo_destroy (d->cr); + + if (d->picture) + XRenderFreePicture (xdisplay, d->picture); + + gwd_decor_frame_unref (switcher_window->frame); g_free (switcher_window); switcher_window = NULL; } @@ -301,32 +390,14 @@ update_switcher_window (Window popup, XGetGeometry (gdk_x11_get_default_xdisplay (), popup, &root_return, &x, &y, &width, &height, &border, &depth); - decor_get_default_layout (&switcher_context, width, 1, &d->border_layout); - - width = d->border_layout.width; - height = d->border_layout.height; - d->decorated = FALSE; d->draw = draw_switcher_decoration; + d->frame = gwd_get_decor_frame ("switcher"); - if (!d->pixmap && switcher_pixmap) - { - g_object_ref (G_OBJECT (switcher_pixmap)); - - d->pixmap = switcher_pixmap; - } - - if (!d->buffer_pixmap && switcher_buffer_pixmap) - { - g_object_ref (G_OBJECT (switcher_buffer_pixmap)); - d->buffer_pixmap = switcher_buffer_pixmap; - } + decor_get_default_layout (&d->frame->window_context, width, 1, &d->border_layout); - if (!d->width) - d->width = switcher_width; - - if (!d->height) - d->height = switcher_height; + width = d->border_layout.width; + height = d->border_layout.height; selected_win = wnck_window_get (selected); if (selected_win) @@ -346,7 +417,7 @@ update_switcher_window (Window popup, { if (!d->layout) { - d->layout = pango_layout_new (pango_context); + d->layout = pango_layout_new (d->frame->pango_context); if (d->layout) pango_layout_set_wrap (d->layout, PANGO_WRAP_CHAR); } @@ -355,8 +426,8 @@ update_switcher_window (Window popup, { int tw; - tw = width - switcher_context.left_space - - switcher_context.right_space - 64; + tw = width - d->frame->window_context.left_space - + d->frame->window_context.right_space - 64; pango_layout_set_auto_dir (d->layout, FALSE); pango_layout_set_width (d->layout, tw * PANGO_SCALE); pango_layout_set_text (d->layout, name, name_length); @@ -399,23 +470,17 @@ update_switcher_window (Window popup, switcher_selected_window = selected; } - pixmap = create_pixmap (width, height, 32); + pixmap = create_pixmap (width, height, d->frame->style_window_rgba); if (!pixmap) return FALSE; - buffer_pixmap = create_pixmap (width, height, 32); + buffer_pixmap = create_pixmap (width, height, d->frame->style_window_rgba); if (!buffer_pixmap) { g_object_unref (G_OBJECT (pixmap)); return FALSE; } - if (switcher_pixmap) - g_object_unref (G_OBJECT (switcher_pixmap)); - - if (switcher_buffer_pixmap) - g_object_unref (G_OBJECT (switcher_buffer_pixmap)); - if (d->pixmap) g_object_unref (G_OBJECT (d->pixmap)); @@ -428,12 +493,6 @@ update_switcher_window (Window popup, if (d->picture) XRenderFreePicture (xdisplay, d->picture); - switcher_pixmap = pixmap; - switcher_buffer_pixmap = buffer_pixmap; - - switcher_width = width; - switcher_height = height; - g_object_ref (G_OBJECT (pixmap)); g_object_ref (G_OBJECT (buffer_pixmap)); diff --git a/gtk/window-decorator/tooltip.c b/gtk/window-decorator/tooltip.c index 20c9aef..3855448 100644 --- a/gtk/window-decorator/tooltip.c +++ b/gtk/window-decorator/tooltip.c @@ -1,3 +1,24 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + */ + #include "gtk-window-decorator.h" /* stolen from gtktooltip.c */ diff --git a/gtk/window-decorator/util.c b/gtk/window-decorator/util.c index 7e78703..18d723c 100644 --- a/gtk/window-decorator/util.c +++ b/gtk/window-decorator/util.c @@ -1,3 +1,24 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + */ + #include "gtk-window-decorator.h" double diff --git a/gtk/window-decorator/wnck.c b/gtk/window-decorator/wnck.c index fc5fd14..96d2113 100644 --- a/gtk/window-decorator/wnck.c +++ b/gtk/window-decorator/wnck.c @@ -1,5 +1,50 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Reveman <davidr@novell.com> + * + * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com> + * Frames Management: Copright © 2011 Canonical Ltd. + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> + */ + #include "gtk-window-decorator.h" +const gchar * +get_frame_type (WnckWindowType wnck_type) +{ + switch (wnck_type) + { + case WNCK_WINDOW_NORMAL: + return "normal"; + case WNCK_WINDOW_DIALOG: + return "dialog"; + case WNCK_WINDOW_MENU: + return "menu"; + case WNCK_WINDOW_UTILITY: + return "utility"; + default: + return "bare"; + } + + return "normal"; +} + static void window_name_changed (WnckWindow *win) { @@ -78,6 +123,16 @@ window_actions_changed (WnckWindow *win) } void +update_frames_border_extents (gpointer key, + gpointer value, + gpointer user_data) +{ + decor_frame_t *frame = (decor_frame_t *) value; + + (*theme_update_border_extents) (frame); +} + +void decorations_changed (WnckScreen *screen) { GdkDisplay *gdkdisplay; @@ -88,8 +143,13 @@ decorations_changed (WnckScreen *screen) gdkdisplay = gdk_display_get_default (); gdkscreen = gdk_display_get_default_screen (gdkdisplay); + gwd_frames_foreach (set_frames_scales, (gpointer) settings->font); + update_titlebar_font (); - (*theme_update_border_extents) (text_height); + gwd_process_frames (update_frames_border_extents, + window_type_frames, + WINDOW_TYPE_FRAMES_NUM, + NULL); update_shadow (); update_default_decorations (gdkscreen); @@ -129,7 +189,6 @@ decorations_changed (WnckScreen *screen) /* force size update */ d->context = NULL; d->width = d->height = 0; - switcher_width = switcher_height = 0; update_switcher_window (d->prop_xid, select); } @@ -210,6 +269,7 @@ add_frame_window (WnckWindow *win, d->active = wnck_window_is_active (win); d->win = win; + d->frame = gwd_get_decor_frame (get_frame_type (wnck_window_get_window_type (win))); d->last_pos_entered = NULL; attr.event_mask = ButtonPressMask | EnterWindowMask | @@ -442,6 +502,12 @@ remove_frame_window (WnckWindow *win) d->decor_window = NULL; } + if (d->frame) + { + gwd_decor_frame_unref (d->frame); + d->frame = NULL; + } + d->width = 0; d->height = 0; @@ -505,7 +571,7 @@ active_window_changed (WnckScreen *screen) } } -static void +void window_opened (WnckScreen *screen, WnckWindow *win) { @@ -571,7 +637,7 @@ window_opened (WnckScreen *screen, } } -static void +void window_closed (WnckScreen *screen, WnckWindow *win) { diff --git a/plugins/cube/src/cube.cpp b/plugins/cube/src/cube.cpp index 2d66971..9436fdf 100644 --- a/plugins/cube/src/cube.cpp +++ b/plugins/cube/src/cube.cpp @@ -1,4 +1,4 @@ -/* + /* * Copyright © 2005 Novell, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -1678,6 +1678,7 @@ PrivateCubeScreen::PrivateCubeScreen (CompScreen *s) : mRotationState = CubeScreen::RotationNone; mDesktopOpacity = OPAQUE; + mPaintOrder = BTF; mLastOpacityIndex = CubeOptions::InactiveOpacity; diff --git a/plugins/decor/src/decor.cpp b/plugins/decor/src/decor.cpp index 341ab85..d2bfadb 100644 --- a/plugins/decor/src/decor.cpp +++ b/plugins/decor/src/decor.cpp @@ -42,6 +42,130 @@ COMPIZ_PLUGIN_20090315 (decor, DecorPluginVTable) +/* From core */ + +bool +isAncestorTo (CompWindow *window, + CompWindow *candidate) +{ + if (window->transientFor ()) + { + if (window->transientFor () == candidate->id ()) + return true; + + window = screen->findWindow (window->transientFor ()); + if (window) + return isAncestorTo (window, candidate); + } + + return false; +} + + +/* Make shadows look nice, don't paint shadows on top of + * things they don't make sense on top of, eg, menus + * need shadows but they don't need to be painted when + * another menu is adjacent and covering the shadow + * region. Also panel shadows are nice, but not + * when they obscure client window shadows + * + * We need to use the current clip region here + * and take an intersection of that to ensure + * that we don't unintentionally expand the clip + * region that core already reduced by doing + * occlusion detection + */ +void +DecorWindow::computeShadowRegion () +{ + shadowRegion = CompRegion (window->outputRect ()); + + if (window->type () == CompWindowTypeDockMask) + { + /* windows above this one in the stack should + * clip the shadow */ + + CompWindowList::iterator it = std::find (screen->windows ().begin (), + screen->windows ().end (), + window); + + for (it--; it != screen->windows ().end (); it--) + { + CompRegion inter; + + if (!(*it)->isViewable ()) + continue; + + if ((*it)->type () & CompWindowTypeDesktopMask) + continue; + + inter = shadowRegion.intersected ((*it)->inputRect ()); + + if (!inter.isEmpty ()) + shadowRegion = shadowRegion.subtracted (inter); + + } + } + else if (window->type () == CompWindowTypeDropdownMenuMask || + window->type () == CompWindowTypePopupMenuMask) + { + /* Other transient menus should clip + * this menu's shadows, also the panel + * which is a transient parent should + * too */ + + CompWindowList::iterator it = std::find (screen->windows ().begin (), + screen->windows ().end (), + window); + + for (it--; it != screen->windows ().end (); it--) + { + CompRegion inter; + + if (!(*it)->isViewable ()) + continue; + + if (!((*it)->type () == CompWindowTypeDropdownMenuMask || + (*it)->type () == CompWindowTypePopupMenuMask || + (*it)->type () == CompWindowTypeDockMask)) + continue; + + /* window needs to be a transient parent */ + if (!isAncestorTo (window, (*it))) + continue; + + inter = shadowRegion.intersected ((*it)->inputRect ()); + + if (!inter.isEmpty ()) + shadowRegion = shadowRegion.subtracted (inter); + } + + /* If the region didn't change, then it is safe to + * say that that this window was probably the first + * menu in the "chain" of dropdown menus that comes + * from a menu-bar - in that case there isn't any + * window that the shadow would necessarily occlude + * here so clip the shadow to the top of the input + * rect. + * + * FIXME: We need a better way to detect exactly + * where the menubar is for the dropdown menu, + * that will look a lot better. + */ + if (window->type () == CompWindowTypeDropdownMenuMask && + shadowRegion == CompRegion (window->outputRect ())) + { + CompRect area (window->outputRect ().x1 (), + window->outputRect ().y1 (), + window->outputRect ().width (), + window->inputRect ().y1 () - + window->outputRect ().y1 ()); + + shadowRegion = shadowRegion.subtracted (area); + } + } +} + bool DecorWindow::glDraw (const GLMatrix &transform, GLFragment::Attrib &attrib, @@ -53,7 +177,7 @@ DecorWindow::glDraw (const GLMatrix &transform, status = gWindow->glDraw (transform, attrib, region, mask); const CompRegion reg = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ? - infiniteRegion : region; + infiniteRegion : shadowRegion.intersected (region); if (wd && !reg.isEmpty () && wd->decor->type == WINDOW_DECORATION_TYPE_PIXMAP) @@ -721,9 +845,7 @@ DecorWindow::update (bool allowDecoration) if (decorate) { if (decor && checkSize (decor)) - { decoration = decor; - } else { @@ -763,7 +885,10 @@ DecorWindow::update (bool allowDecoration) return false; if (dScreen->cmActive) + { cWindow->damageOutputExtents (); + computeShadowRegion (); + } if (old) { @@ -862,10 +987,8 @@ DecorWindow::update (bool allowDecoration) void DecorWindow::updateFrame () { - if (!wd || !(wd->decor->input.left || wd->decor->input.left || - wd->decor->input.left || wd->decor->input.bottom) || - !(wd->decor->maxInput.left || wd->decor->maxInput.left || - wd->decor->maxInput.left || wd->decor->maxInput.bottom) || + if (!wd || !(window->input ().left || window->input ().right || + window->input ().top || window->input ().bottom) || (wd->decor->type == WINDOW_DECORATION_TYPE_PIXMAP && outputFrame) || (wd->decor->type == WINDOW_DECORATION_TYPE_WINDOW && inputFrame)) { @@ -874,6 +997,7 @@ DecorWindow::updateFrame () XDeleteProperty (screen->dpy (), window->id (), dScreen->inputFrameAtom); XDestroyWindow (screen->dpy (), inputFrame); + inputFrame = None; frameRegion = CompRegion (); @@ -899,10 +1023,8 @@ DecorWindow::updateFrame () oldHeight = 0; } } - if (wd && (wd->decor->input.left || wd->decor->input.left || - wd->decor->input.left || wd->decor->input.bottom || - wd->decor->maxInput.left || wd->decor->maxInput.left || - wd->decor->maxInput.left || wd->decor->maxInput.bottom)) + if (wd && (window->input ().left || window->input ().right || + window->input ().top || window->input ().bottom)) { if (wd->decor->type == WINDOW_DECORATION_TYPE_PIXMAP) updateInputFrame (); @@ -1308,6 +1430,16 @@ DecorWindow::windowNotify (CompWindowNotify n) switch (n) { + case CompWindowNotifyMap: + case CompWindowNotifyUnmap: + if (dScreen->cmActive) + { + foreach (CompWindow *cw, DecorScreen::get (screen)->cScreen->getWindowPaintList ()) + { + DecorWindow::get (cw)->computeShadowRegion (); + } + } + break; case CompWindowNotifyUnreparent: /* We don't get a DestroyNotify when the wrapper window * or frame window gets destroyed, which destroys our @@ -1475,6 +1607,16 @@ DecorScreen::handleEvent (XEvent *event) if (w) DecorWindow::get (w)->update (true); } + else if (event->xproperty.atom == XA_WM_TRANSIENT_FOR) + { + if (cmActive) + { + foreach (CompWindow *cw, cScreen->getWindowPaintList ()) + { + DecorWindow::get (cw)->computeShadowRegion (); + } + } + } else { if (event->xproperty.window == screen->root ()) @@ -1756,6 +1898,15 @@ DecorWindow::moveNotify (int dx, int dy, bool immediate) } updateReg = true; + if (dScreen->cmActive) + { + foreach (CompWindow *cw, + DecorScreen::get (screen)->cScreen->getWindowPaintList ()) + { + DecorWindow::get (cw)->computeShadowRegion (); + } + } + window->moveNotify (dx, dy, immediate); } @@ -1787,6 +1938,15 @@ DecorWindow::resizeNotify (int dx, int dy, int dwidth, int dheight) updateDecorationScale (); updateReg = true; + if (dScreen->cmActive) + { + foreach (CompWindow *cw, + DecorScreen::get (screen)->cScreen->getWindowPaintList ()) + { + DecorWindow::get (cw)->computeShadowRegion (); + } + } + window->resizeNotify (dx, dy, dwidth, dheight); } @@ -1885,7 +2045,10 @@ DecorScreen::DecorScreen (CompScreen *s) : windowDefault.input.top = 1; windowDefault.input.bottom = 0; - windowDefault.maxInput = windowDefault.output = windowDefault.input; + windowDefault.border = windowDefault.maxBorder = + windowDefault.maxInput = windowDefault.output = + windowDefault.input; + windowDefault.refCount = 1; cmActive = (cScreen) ? cScreen->compositingActive () && @@ -1933,6 +2096,17 @@ DecorWindow::DecorWindow (CompWindow *w) : { WindowInterface::setHandler (window); + /* FIXME :DecorWindow::update can call updateWindowOutputExtents + * which will call a zero-diff resizeNotify. Since this window + * might be part of a startup procedure, we can't assume that + * all other windows in the list are necessarily safe to use + * (since DecorWindow::DecorWindow might not have been called + * for them) so we need to turn off resize notifications + * and turn them back on once we're done updating the decoration + */ + + window->resizeNotifySetEnabled (this, false); + if (dScreen->cmActive) { gWindow = GLWindow::get (w); @@ -1948,6 +2122,8 @@ DecorWindow::DecorWindow (CompWindow *w) : if (w->shaded () || w->isViewable ()) update (true); + + window->resizeNotifySetEnabled (this, true); } diff --git a/plugins/decor/src/decor.h b/plugins/decor/src/decor.h index cf33cc6..71191b2 100644 --- a/plugins/decor/src/decor.h +++ b/plugins/decor/src/decor.h @@ -178,6 +178,8 @@ class DecorWindow : bool damageRect (bool, const CompRect &); + void computeShadowRegion (); + bool glDraw (const GLMatrix &, GLFragment::Attrib &, const CompRegion &, unsigned int); @@ -216,6 +218,7 @@ class DecorWindow : Decoration *decor; CompRegion frameRegion; + CompRegion shadowRegion; Window inputFrame; Window outputFrame; diff --git a/plugins/switcher/src/switcher.cpp b/plugins/switcher/src/switcher.cpp index 71eb54e..d8b09f2 100644 --- a/plugins/switcher/src/switcher.cpp +++ b/plugins/switcher/src/switcher.cpp @@ -303,13 +303,7 @@ SwitchScreen::initiate (SwitchWindowSelection selection, if (popupWindow && showPopup) { - CompWindow *w; - - w = screen->findWindow (popupWindow); - if (w && (w->state () & CompWindowStateHiddenMask)) - w->show (); - else - XMapWindow (screen->dpy (), popupWindow); + XMapWindow (screen->dpy (), popupWindow); setSelectedWindowHint (); } @@ -357,22 +351,11 @@ switchTerminate (CompAction *action, SWITCH_SCREEN (screen); - if (ss->grabIndex) { - CompWindow *w; - if (ss->popupWindow) { - w = screen->findWindow (ss->popupWindow); - if (w && w->managed () && w->mapNum ()) - { - w->hide (); - } - else - { - XUnmapWindow (screen->dpy (), ss->popupWindow); - } + XUnmapWindow (screen->dpy (), ss->popupWindow); } ss->switching = false; diff --git a/src/screen.cpp b/src/screen.cpp index c9af3df..e56d2e0 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -4531,6 +4531,7 @@ CompScreen::init (const char *name) XDefineCursor (dpy, priv->root, priv->normalCursor); XUngrabServer (dpy); + XSync (dpy, FALSE); priv->setAudibleBell (priv->optionGetAudibleBell ()); @@ -4541,6 +4542,13 @@ CompScreen::init (const char *name) priv->addScreenActions (); + /* Need to set a default here so that the value isn't uninitialized + * when loading plugins FIXME: Should find a way to initialize options + * first and then set this value, or better yet, tie this value directly + * to the option */ + priv->vpSize.setWidth (priv->optionGetHsize ()); + priv->vpSize.setHeight (priv->optionGetVsize ()); + priv->initialized = true; /* TODO: Bailout properly when screenInitPlugins fails @@ -4554,6 +4562,9 @@ CompScreen::init (const char *name) /* The active plugins list might have been changed - load any * new plugins */ + priv->vpSize.setWidth (priv->optionGetHsize ()); + priv->vpSize.setHeight (priv->optionGetVsize ()); + if (priv->dirtyPluginList) priv->updatePlugins (); @@ -4583,8 +4594,7 @@ CompScreen::init (const char *name) } } - priv->vpSize.setWidth (priv->optionGetHsize ()); - priv->vpSize.setHeight (priv->optionGetVsize ()); + i = 0; /* enforce restack on all windows */ i = 0; diff --git a/src/timer.cpp b/src/timer.cpp index d01a8e7..750d957 100644 --- a/src/timer.cpp +++ b/src/timer.cpp @@ -1,5 +1,6 @@ /* * Copyright © 2008 Dennis Kasprzyk + * Copyright © 2011 Canonical Ltd. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without |