mutter/src/ui/resizepopup.c

239 lines
6.1 KiB
C
Raw Normal View History

/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Metacity resizing-terminal-window feedback */
2014-05-02 09:34:02 -04:00
/*
* Copyright (C) 2001 Havoc Pennington
2014-05-02 09:34:02 -04:00
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
2014-05-02 09:34:02 -04:00
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include "resizepopup.h"
#include "util-private.h"
#include <gtk/gtk.h>
(Apologies for huge commit; these were done on a transatlantic flight. This is why we need bzr.) 2008-11-22 Thomas Thurman <tthurman@gnome.org> * src/core/all-keybindings.h: "backward", not "backwards" throughout. 2008-11-20 Thomas Thurman <tthurman@gnome.org> * configure.in: turned on -Wall and -Werror in order to trap as many problems as possible. * src/ui/resizepopup.c: added correct #include. * src/ui/theme-viewer.c: initialised variable. * src/core/xprops.c: corrected cast. * src/core/main.c: added warning if chdir() fails. * src/core/schema-bindings.c: checking the return result of fgets(). 2008-11-20 Thomas Thurman <tthurman@gnome.org> Merged screen and window keybinding tables so that we can use just one file for the both. Also incidentally closes #528337. Further efficiencies of scale to come. * src/include/prefs.h: replace META_PREF_*_KEYBINDINGS with META_PREF_KEYBINDINGS * src/core/keybindings.c: replace *_bindings with key_bindings and similar throughout; all window-based functions are now guaranteed to receive a window so don't need to check for themselves (find_handler): moved so it can also be called from rebuild_binding_table * src/core/display-private.h: replace *_bindings with key_bindings * src/core/prefs.c: update_*_binding becomes update_key_binding; (change_notify): tidy up references to "enormous if statement" since it's almost entirely gone now * src/core/all-keybindings.h: new merged version of screen-bindings.h and window-bindings.h. svn path=/trunk/; revision=4022
2008-11-22 14:02:54 -05:00
#include <gdk/gdkx.h>
struct _MetaResizePopup
{
GtkWidget *size_window;
GtkWidget *size_label;
Display *display;
2014-05-02 09:34:02 -04:00
int screen_number;
int vertical_size;
int horizontal_size;
2014-05-02 09:34:02 -04:00
gboolean showing;
2014-05-02 09:34:02 -04:00
2006-03-29 11:05:23 -05:00
MetaRectangle rect;
};
MetaResizePopup*
meta_ui_resize_popup_new (Display *display,
int screen_number)
{
MetaResizePopup *popup;
popup = g_new0 (MetaResizePopup, 1);
popup->display = display;
popup->screen_number = screen_number;
2014-05-02 09:34:02 -04:00
return popup;
}
void
meta_ui_resize_popup_free (MetaResizePopup *popup)
{
g_return_if_fail (popup != NULL);
2014-05-02 09:34:02 -04:00
if (popup->size_window)
gtk_widget_destroy (popup->size_window);
2014-05-02 09:34:02 -04:00
g_free (popup);
}
static gboolean
size_window_draw (GtkWidget *widget,
cairo_t *cr,
MetaResizePopup *popup)
{
GtkStyleContext *context;
gint width, height;
context = gtk_widget_get_style_context (widget);
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
gtk_render_background (context, cr, 0, 0, width, height);
gtk_render_frame (context, cr, 0, 0, width, height);
return FALSE;
}
static void
ensure_size_window (MetaResizePopup *popup)
{
GdkVisual *visual;
GdkScreen *screen;
if (popup->size_window)
return;
popup->size_window = gtk_window_new (GTK_WINDOW_POPUP);
screen = gdk_display_get_screen (gdk_x11_lookup_xdisplay (popup->display),
popup->screen_number);
visual = gdk_screen_get_rgba_visual (screen);
gtk_window_set_screen (GTK_WINDOW (popup->size_window), screen);
if (visual != NULL)
gtk_widget_set_visual (popup->size_window, visual);
gtk_window_set_type_hint (GTK_WINDOW (popup->size_window),
GDK_WINDOW_TYPE_HINT_TOOLTIP);
gtk_window_set_resizable (GTK_WINDOW (popup->size_window), FALSE);
gtk_widget_set_app_paintable (popup->size_window, TRUE);
gtk_style_context_add_class (gtk_widget_get_style_context (popup->size_window),
GTK_STYLE_CLASS_TOOLTIP);
g_signal_connect (popup->size_window, "draw",
G_CALLBACK (size_window_draw), popup);
popup->size_label = gtk_label_new ("");
g_object_set (popup->size_label, "margin", 6, NULL);
gtk_container_add (GTK_CONTAINER (popup->size_window), popup->size_label);
gtk_widget_show (popup->size_label);
}
static void
update_size_window (MetaResizePopup *popup)
{
char *str;
int x, y;
int width, height;
2014-05-02 09:34:02 -04:00
g_return_if_fail (popup->size_window != NULL);
2014-05-02 09:34:02 -04:00
/* Translators: This represents the size of a window. The first number is
* the width of the window and the second is the height.
*/
str = g_strdup_printf (_("%d x %d"),
popup->horizontal_size,
popup->vertical_size);
gtk_label_set_text (GTK_LABEL (popup->size_label), str);
g_free (str);
gtk_window_get_size (GTK_WINDOW (popup->size_window), &width, &height);
2006-03-29 11:05:23 -05:00
x = popup->rect.x + (popup->rect.width - width) / 2;
y = popup->rect.y + (popup->rect.height - height) / 2;
2014-05-02 09:34:02 -04:00
if (gtk_widget_get_realized (popup->size_window))
{
/* using move_resize to avoid jumpiness */
gdk_window_move_resize (gtk_widget_get_window (popup->size_window),
x, y,
width, height);
}
else
{
gtk_window_move (GTK_WINDOW (popup->size_window),
x, y);
}
}
static void
sync_showing (MetaResizePopup *popup)
{
if (popup->showing)
{
if (popup->size_window)
gtk_widget_show (popup->size_window);
2014-05-02 09:34:02 -04:00
if (popup->size_window && gtk_widget_get_realized (popup->size_window))
gdk_window_raise (gtk_widget_get_window (popup->size_window));
}
else
{
if (popup->size_window)
gtk_widget_hide (popup->size_window);
}
}
void
meta_ui_resize_popup_set (MetaResizePopup *popup,
2006-03-29 11:05:23 -05:00
MetaRectangle rect,
int base_width,
int base_height,
int width_inc,
int height_inc)
{
gboolean need_update_size;
int display_w, display_h;
2014-05-02 09:34:02 -04:00
g_return_if_fail (popup != NULL);
need_update_size = FALSE;
2014-05-02 09:34:02 -04:00
2006-03-29 11:05:23 -05:00
display_w = rect.width - base_width;
if (width_inc > 0)
display_w /= width_inc;
2006-03-29 11:05:23 -05:00
display_h = rect.height - base_height;
if (height_inc > 0)
display_h /= height_inc;
2006-03-29 11:05:23 -05:00
if (!meta_rectangle_equal(&popup->rect, &rect) ||
display_w != popup->horizontal_size ||
display_h != popup->vertical_size)
need_update_size = TRUE;
2014-05-02 09:34:02 -04:00
2006-03-29 11:05:23 -05:00
popup->rect = rect;
popup->vertical_size = display_h;
popup->horizontal_size = display_w;
2014-05-02 09:34:02 -04:00
if (need_update_size)
{
ensure_size_window (popup);
update_size_window (popup);
}
2014-05-02 09:34:02 -04:00
sync_showing (popup);
}
void
meta_ui_resize_popup_set_showing (MetaResizePopup *popup,
gboolean showing)
{
g_return_if_fail (popup != NULL);
2014-05-02 09:34:02 -04:00
if (showing == popup->showing)
return;
popup->showing = !!showing;
if (popup->showing)
{
ensure_size_window (popup);
update_size_window (popup);
}
2014-05-02 09:34:02 -04:00
sync_showing (popup);
}