Added visual bell feature, fix for 99886.

This commit is contained in:
Bill Haneman 2002-12-17 01:08:29 +00:00
parent 32a8bf50b7
commit e7e47a8b85
16 changed files with 663 additions and 6 deletions

130
ChangeLog
View File

@ -1,3 +1,133 @@
2002-12-16 Bill Haneman <bill.haneman@sun.com>
* configure.in:
Check for XKB extension.
* src/Makefile.am:
Added bell.c and bell.h to metacity sources.
* src/common.h:
(MetaFrameFlags):
Added META_FRAME_IS_FLASHING flag.
* src/frame.h:
(MetaFrame): Added is_flashing field.
* src/frame.c:
(meta_window_ensure_frame):
Initialize the is_flashing flag to FALSE.
(meta_frame_get_flags):
Handle the FRAME_IS_FLASHING flag.
(meta_window_destroy_frame):
Call meta_bell_notify_frame_destroy.
* src/prefs.h:
(MetaPreference):
Added META_PREF_VISUAL_BELL, META_PREF_AUDIBLE_BELL,
META_PREF_VISUAL_BELL_TYPE.
(MetaVisualBellType): New enum.
(meta_prefs_get_visual_bell, meta_prefs_bell_is_audible):
(meta_prefs_get_visual_bell_type):
New accessor declarations.
* src/prefs.c:
(#includes): Include "display.h", since we now call
meta_displays_list() in our update func.
(#defines):
Define KEY_VISUAL_BELL, KEY_AUDIBLE_BELL,
and KEY_VISUAL_BELL_TYPE.
(provide_visual_bell, bell_is_audible, visual_bell_type):
New static state variables.
(update_visual_bell): New method to update visual-bell
boolean settings from keys "visual_bell" and "audible_bell".
(update_visual_bell_type):
New method to update visual-bell type setting.
(visual_bell_type_from_string) :
New method to convert from gconf string to visual-bell
type enum. Only currently recognized values are "fullscreen"
and "frame_flash".
(change_notify):
Handle changes to visual and audible bell properties.
(meta_prefs_get_visual_bell, meta_prefs_bell_is_audible):
(meta_prefs_get_visual_bell_type):
New accessor definitions.
(meta_prefs_init): Added a second call to notify_add,
listens to "/desktop/gnome/interface" as well as "apps/metacity".
Also call the update funcs for the new visual-bell gconf keys.
(meta_preference_to_string):
Handle the visual/audible bell cases.
* src/bell.h:
(meta_bell_notify);
New method, calls a visual notifucation
method based on the visual-bell-type, or none if the type
is unrecognized or invalid.
(meta_bell_set_audible):
New public method for setting the audible bell setting,
used in updater for new gconf key "audible_bell".
(meta_bell_init):
Initialize the bell notification for a display.
(meta_bell_shutdown):
Shutdown the bell notification for a display.
(meta_bell_notify_frame_destroy):
Remove pending idle handlers on notification.
* src/bell.c:
Include "bell.h", and conditionally include <Xll/Xkblib.h>.
(meta_bell_set_audible):
If XKB is present, enable/disable the audible system
bell based on the gconf key /desktop/gnome/interface/audible_bell.
(meta_bell_init):
Query and initialize XKB if present, register for notification
on the bell, and set audible bell according to gconf settings.
(meta_bell_flash_screen):
Maps and unmaps a fullscreen X window (painted white, then
black), which causes a fullscreen 'flash' transient.
(meta_bell_flash_window_frame):
Flashes the titlebar of a specified window.
(meta_bell_flash_frame):
Calls meta_bell_flash_window_frame on the window which
was the source of the current bell event, or the currently
focussed window if the event source cannot be determined.
(meta_bell_unflash_frame):
Restore the frame's appearance to normal.
(meta_bell_flash_fullscreen):
Call meta_bell_flash_fullscreen for all screens.
(meta_bell_shutdown):
New method.
(meta_bell_notify_frame_destroy):
Remove pending idle handlers on notification,
testing for frame->is_flashing first.
* src/display.h:
(MetaDisplay): Added xkb_base_event_type field.
* src/display.c:
Check for XKB and include "X11/XKBlib.h" if present.
(meta_display_open): Call meta_bell_init.
(event_callback): Call meta_bell_notify
when event comes from XKB and is XkbBellNotify
(prefs_changed_callback):
Handle META_PREF_AUDIBLE_BELL notification.
* src/screen.h:
(MetaScreen): Add flash_window field.
* src/screen.c:
(meta_screen_new):
Initialize flash_window field.
* src/theme.c:
(theme_get_style):
New heuristic for focus-style, to invert sense of focus
flag when META_FRAME_IS_FLASHING flag is set.
* src/metacity.schemas.in:
Added scheme information for
/apps/metacity/general/visual_bell,
/apps/metacity/general/audible_bell, and
/apps/metacity/general/visual_bell_type.
2002-12-16 Havoc Pennington <hp@pobox.com> 2002-12-16 Havoc Pennington <hp@pobox.com>
* src/window-props.c (init_wm_name): argh, screwed that up. get * src/window-props.c (init_wm_name): argh, screwed that up. get

View File

@ -221,6 +221,17 @@ if test "x$found_shape" = "xyes"; then
AC_DEFINE(HAVE_SHAPE, , [Have the shape extension library]) AC_DEFINE(HAVE_SHAPE, , [Have the shape extension library])
fi fi
found_xkb=no
AC_CHECK_LIB(X11, XkbQueryExtension,
[AC_CHECK_HEADER(X11/XKBlib.h,
found_xkb=yes)],
, $ALL_X_LIBS)
if test "x$found_xkb" = "xyes"; then
AC_DEFINE(HAVE_XKB, , [Have keyboard extension library])
fi
RANDR_LIBS= RANDR_LIBS=
found_randr=no found_randr=no
AC_CHECK_LIB(Xrandr, XRRUpdateConfiguration, AC_CHECK_LIB(Xrandr, XRRUpdateConfiguration,

View File

@ -11,6 +11,8 @@ EGGFILES= \
metacity_SOURCES= \ metacity_SOURCES= \
async-getprop.c \ async-getprop.c \
async-getprop.h \ async-getprop.h \
bell.h \
bell.c \
common.h \ common.h \
core.c \ core.c \
core.h \ core.h \

250
src/bell.c Normal file
View File

@ -0,0 +1,250 @@
/* Metacity visual bell */
/*
* Copyright (C) 2002 Sun Microsystems Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <config.h>
#include "bell.h"
#include "screen.h"
#include "prefs.h"
static void
meta_bell_flash_screen (MetaDisplay *display,
MetaScreen *screen)
{
Window root = screen->xroot;
int width = screen->width;
int height = screen->height;
if (screen->flash_window == None)
{
Visual *visual = CopyFromParent;
XSetWindowAttributes xswa;
int depth = CopyFromParent;
xswa.save_under = True;
xswa.override_redirect = True;
/*
* TODO: use XGetVisualInfo and determine which is an
* overlay, if one is present, and use the Overlay visual
* for this window (for performance reasons).
* Not sure how to tell this yet...
*/
screen->flash_window = XCreateWindow (display->xdisplay, root,
0, 0, width, height,
0, depth,
InputOutput,
visual,
/* note: XSun doesn't like SaveUnder here */
CWSaveUnder | CWOverrideRedirect,
&xswa);
XSelectInput (display->xdisplay, screen->flash_window, ExposureMask);
XMapWindow (display->xdisplay, screen->flash_window);
XSync (display->xdisplay, False);
XFlush (display->xdisplay);
XUnmapWindow (display->xdisplay, screen->flash_window);
}
else
{
/* just draw something in the window */
GC gc = XCreateGC (display->xdisplay, screen->flash_window, 0, NULL);
XMapWindow (display->xdisplay, screen->flash_window);
XSetForeground (display->xdisplay, gc,
WhitePixel (display->xdisplay,
XScreenNumberOfScreen (screen->xscreen)));
XFillRectangle (display->xdisplay, screen->flash_window, gc,
0, 0, width, height);
XSetForeground (display->xdisplay, gc,
BlackPixel (display->xdisplay,
XScreenNumberOfScreen (screen->xscreen)));
XFillRectangle (display->xdisplay, screen->flash_window, gc,
0, 0, width, height);
XFlush (display->xdisplay);
XSync (display->xdisplay, False);
XUnmapWindow (display->xdisplay, screen->flash_window);
}
XFlush (display->xdisplay);
}
#ifdef HAVE_XKB
static void
meta_bell_flash_fullscreen (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
{
XkbBellNotifyEvent *xkb_bell_ev = (XkbBellNotifyEvent *) xkb_ev;
MetaScreen *screen;
g_assert (xkb_ev->xkb_type == XkbBellNotify);
if (xkb_bell_ev->window != None)
{
screen = meta_display_screen_for_xwindow (display, xkb_bell_ev->window);
if (screen)
meta_bell_flash_screen (display, screen);
}
else
{
GSList *screen_list = display->screens;
while (screen_list)
{
screen = (MetaScreen *) screen_list->data;
meta_bell_flash_screen (display, screen);
screen_list = screen_list->next;
}
}
}
static gboolean
meta_bell_unflash_frame (gpointer data)
{
MetaFrame *frame = (MetaFrame *) data;
frame->is_flashing = 0;
meta_frame_queue_draw (frame);
return FALSE;
}
static void
meta_bell_flash_window_frame (MetaWindow *window)
{
g_assert (window->frame != NULL);
window->frame->is_flashing = 1;
meta_frame_queue_draw (window->frame);
g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, 100,
meta_bell_unflash_frame, window->frame, NULL);
}
static void
meta_bell_flash_frame (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
{
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev;
MetaWindow *window;
g_assert (xkb_ev->xkb_type == XkbBellNotify);
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
if (!window && (display->focus_window->frame))
{
window = display->focus_window;
}
if (window)
{
meta_bell_flash_window_frame (window);
}
else /* revert to fullscreen flash if there's no focussed window */
{
meta_bell_flash_fullscreen (display, xkb_ev);
}
}
static void
meta_bell_visual_notify (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
{
switch (meta_prefs_get_visual_bell_type ())
{
case META_VISUAL_BELL_FULLSCREEN_FLASH:
meta_bell_flash_fullscreen (display, xkb_ev);
break;
case META_VISUAL_BELL_FRAME_FLASH:
meta_bell_flash_frame (display, xkb_ev); /* does nothing yet */
break;
case META_VISUAL_BELL_INVALID:
/* do nothing */
break;
}
}
void
meta_bell_notify (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
{
/* flash something */
if (meta_prefs_get_visual_bell ())
meta_bell_visual_notify (display, xkb_ev);
}
#endif
void
meta_bell_set_audible (MetaDisplay *display, gboolean audible)
{
#ifdef HAVE_XKB
XkbChangeEnabledControls (display->xdisplay,
XkbUseCoreKbd,
XkbAudibleBellMask,
audible ? XkbAudibleBellMask : 0);
#endif
}
gboolean
meta_bell_init (MetaDisplay *display)
{
#ifdef HAVE_XKB
int xkb_base_error_type, xkb_opcode;
if (!XkbQueryExtension (display->xdisplay, &xkb_opcode,
&display->xkb_base_event_type,
&xkb_base_error_type,
NULL, NULL))
{
display->xkb_base_event_type = -1;
g_message ("could not find XKB extension.");
return FALSE;
}
else
{
unsigned int mask = XkbBellNotifyMask;
gboolean visual_bell_auto_reset = FALSE;
/* TRUE if and when non-broken version is available */
XkbSelectEvents (display->xdisplay,
XkbUseCoreKbd,
XkbBellNotifyMask,
XkbBellNotifyMask);
XkbChangeEnabledControls (display->xdisplay,
XkbUseCoreKbd,
XkbAudibleBellMask,
meta_prefs_bell_is_audible ()
? XkbAudibleBellMask : 0);
if (visual_bell_auto_reset) {
XkbSetAutoResetControls (display->xdisplay,
XkbAudibleBellMask,
&mask,
&mask);
}
return TRUE;
}
#endif
return FALSE;
}
void
meta_bell_shutdown (MetaDisplay *display)
{
#ifdef HAVE_XKB
/* TODO: persist initial bell state in display, reset here */
XkbChangeEnabledControls (display->xdisplay,
XkbUseCoreKbd,
XkbAudibleBellMask,
XkbAudibleBellMask);
#endif
}
void
meta_bell_notify_frame_destroy (MetaFrame *frame)
{
if (frame->is_flashing)
g_idle_remove_by_data (frame);
}

34
src/bell.h Normal file
View File

@ -0,0 +1,34 @@
/* Metacity visual bell */
/*
* Copyright (C) 2002 Sun Microsystems Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifdef HAVE_XKB
#include <X11/XKBlib.h>
#endif
#include "display.h"
#include "frame.h"
#ifdef HAVE_XKB
void meta_bell_notify (MetaDisplay *display, XkbAnyEvent *xkb_ev);
#endif
void meta_bell_set_audible (MetaDisplay *display, gboolean audible);
gboolean meta_bell_init (MetaDisplay *display);
void meta_bell_shutdown (MetaDisplay *display);
void meta_bell_notify_frame_destroy (MetaFrame *frame);

View File

@ -42,7 +42,8 @@ typedef enum
META_FRAME_MAXIMIZED = 1 << 9, META_FRAME_MAXIMIZED = 1 << 9,
META_FRAME_ALLOWS_SHADE = 1 << 10, META_FRAME_ALLOWS_SHADE = 1 << 10,
META_FRAME_ALLOWS_MOVE = 1 << 11, META_FRAME_ALLOWS_MOVE = 1 << 11,
META_FRAME_FULLSCREEN = 1 << 12 META_FRAME_FULLSCREEN = 1 << 12,
META_FRAME_IS_FLASHING = 1 << 13
} MetaFrameFlags; } MetaFrameFlags;
typedef enum typedef enum

View File

@ -34,6 +34,7 @@
#include "prefs.h" #include "prefs.h"
#include "resizepopup.h" #include "resizepopup.h"
#include "workspace.h" #include "workspace.h"
#include "bell.h"
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/cursorfont.h> #include <X11/cursorfont.h>
#ifdef HAVE_SOLARIS_XINERAMA #ifdef HAVE_SOLARIS_XINERAMA
@ -42,6 +43,9 @@
#ifdef HAVE_XFREE_XINERAMA #ifdef HAVE_XFREE_XINERAMA
#include <X11/extensions/Xinerama.h> #include <X11/extensions/Xinerama.h>
#endif #endif
#ifdef HAVE_XKB
#include <X11/XKBlib.h>
#endif
#include <string.h> #include <string.h>
#define USE_GDK_DISPLAY #define USE_GDK_DISPLAY
@ -305,6 +309,8 @@ meta_display_open (const char *name)
/* we have to go ahead and do this so error handlers work */ /* we have to go ahead and do this so error handlers work */
all_displays = g_slist_prepend (all_displays, display); all_displays = g_slist_prepend (all_displays, display);
meta_bell_init (display);
meta_display_init_keys (display); meta_display_init_keys (display);
update_window_grab_modifiers (display); update_window_grab_modifiers (display);
@ -1822,6 +1828,19 @@ event_callback (XEvent *event,
} }
break; break;
default: default:
#ifdef HAVE_XKB
if (event->type == display->xkb_base_event_type)
{
XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;
switch (xkb_ev->xkb_type)
{
case XkbBellNotify:
meta_bell_notify (display, xkb_ev);
break;
}
}
#endif
break; break;
} }
@ -3846,4 +3865,9 @@ prefs_changed_callback (MetaPreference pref,
g_slist_free (windows); g_slist_free (windows);
} }
else if (pref == META_PREF_AUDIBLE_BELL)
{
MetaDisplay *display = data;
meta_bell_set_audible (display, meta_prefs_bell_is_audible ());
}
} }

View File

@ -245,6 +245,9 @@ struct _MetaDisplay
MetaRectangle grab_current_window_pos; MetaRectangle grab_current_window_pos;
MetaResizePopup *grab_resize_popup; MetaResizePopup *grab_resize_popup;
GTimeVal grab_last_moveresize_time; GTimeVal grab_last_moveresize_time;
#ifdef HAVE_XKB
int xkb_base_event_type;
#endif
#ifdef HAVE_XSYNC #ifdef HAVE_XSYNC
/* alarm monitoring client's _METACITY_UPDATE_COUNTER */ /* alarm monitoring client's _METACITY_UPDATE_COUNTER */
XSyncAlarm grab_update_alarm; XSyncAlarm grab_update_alarm;

View File

@ -21,6 +21,7 @@
#include <config.h> #include <config.h>
#include "frame.h" #include "frame.h"
#include "bell.h"
#include "errors.h" #include "errors.h"
#include "keybindings.h" #include "keybindings.h"
@ -58,6 +59,7 @@ meta_window_ensure_frame (MetaWindow *window)
frame->current_cursor = 0; frame->current_cursor = 0;
frame->mapped = FALSE; frame->mapped = FALSE;
frame->is_flashing = FALSE;
attrs.event_mask = EVENT_MASK; attrs.event_mask = EVENT_MASK;
@ -159,6 +161,7 @@ meta_window_destroy_frame (MetaWindow *window)
frame = window->frame; frame = window->frame;
meta_bell_notify_frame_destroy (frame);
meta_ui_remove_frame (window->screen->ui, frame->xwindow); meta_ui_remove_frame (window->screen->ui, frame->xwindow);
/* Unparent the client window; it may be destroyed, /* Unparent the client window; it may be destroyed,
@ -255,6 +258,9 @@ meta_frame_get_flags (MetaFrame *frame)
if (frame->window->fullscreen) if (frame->window->fullscreen)
flags |= META_FRAME_FULLSCREEN; flags |= META_FRAME_FULLSCREEN;
if (frame->is_flashing)
flags |= META_FRAME_IS_FLASHING;
return flags; return flags;
} }

View File

@ -57,6 +57,7 @@ struct _MetaFrame
int bottom_height; int bottom_height;
guint mapped : 1; guint mapped : 1;
guint is_flashing : 1; /* used by the visual bell flash */
}; };
void meta_window_ensure_frame (MetaWindow *window); void meta_window_ensure_frame (MetaWindow *window);

View File

@ -177,6 +177,57 @@
</locale> </locale>
</schema> </schema>
<schema>
<key>/apps/metacity/visual_bell</key>
<applyto>/apps/metacity/general/visual_bell</applyto>
<owner>metacity</owner>
<type>bool</type>
<default>false</default>
<locale name="C">
<short>Enable Visual Bell</short>
<long>Turns on a visual indication when an application or the system
issues a 'bell' or 'beep'; useful for the hard-of-hearing and for use
in noisy environments, or when 'audible bell' is off.
</long>
</locale>
</schema>
<schema>
<key>/schemas/apps/metacity/general/audible_bell</key>
<applyto>/apps/metacity/general/audible_bell</applyto>
<owner>metacity</owner>
<type>bool</type>
<default>true</default>
<locale name="C">
<short>System Bell is Audible</short>
<long>Determines whether applications or the system can generate audible
'beeps'; may be used in conjunction with 'visual bell' to
allow silent 'beeps'.
</long>
</locale>
</schema>
<schema>
<key>/schemas/apps/metacity/general/visual_bell_type</key>
<applyto>/apps/metacity/general/visual_bell_type</applyto>
<owner>metacity</owner>
<type>string</type>
<default>fullscreen</default>
<locale name="C">
<short>Visual Bell Type</short>
<long>
Tells Metacity how to implement the visual indication that
the system bell or another application 'bell' indicator has
been rung. Currently there are two valid values, "fullscreen",
which causes a fullscreen white-black flash, and "frame_flash" which
causes the titlebar of the application which sent the bell signal to
flash. If the application which sent the bell is unknown (as is
usually the case for the default "system beep"), the currently
focussed window's titlebar is flashed.
</long>
</locale>
</schema>
<schema> <schema>
<key>/schemas/apps/metacity/workspace_names/name</key> <key>/schemas/apps/metacity/workspace_names/name</key>
<applyto>/apps/metacity/workspace_names/name_1</applyto> <applyto>/apps/metacity/workspace_names/name_1</applyto>

View File

@ -54,6 +54,10 @@
#define KEY_WORKSPACE_NAME_PREFIX "/apps/metacity/workspace_names/name_" #define KEY_WORKSPACE_NAME_PREFIX "/apps/metacity/workspace_names/name_"
#define KEY_VISUAL_BELL "/apps/metacity/general/visual_bell"
#define KEY_AUDIBLE_BELL "/apps/metacity/general/audible_bell"
#define KEY_VISUAL_BELL_TYPE "/apps/metacity/general/visual_bell_type"
#ifdef HAVE_GCONF #ifdef HAVE_GCONF
static GConfClient *default_client = NULL; static GConfClient *default_client = NULL;
static GList *changes = NULL; static GList *changes = NULL;
@ -73,6 +77,9 @@ static gboolean application_based = FALSE;
static gboolean disable_workarounds = FALSE; static gboolean disable_workarounds = FALSE;
static gboolean auto_raise = FALSE; static gboolean auto_raise = FALSE;
static gboolean auto_raise_delay = 500; static gboolean auto_raise_delay = 500;
static gboolean provide_visual_bell = TRUE;
static gboolean bell_is_audible = TRUE;
static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_INVALID;
static MetaButtonLayout button_layout = { static MetaButtonLayout button_layout = {
{ {
META_BUTTON_FUNCTION_MENU, META_BUTTON_FUNCTION_MENU,
@ -98,6 +105,8 @@ static gboolean update_titlebar_font (const char *value);
static gboolean update_mouse_button_mods (const char *value); static gboolean update_mouse_button_mods (const char *value);
static gboolean update_focus_mode (const char *value); static gboolean update_focus_mode (const char *value);
static gboolean update_theme (const char *value); static gboolean update_theme (const char *value);
static gboolean update_visual_bell (gboolean v1, gboolean v2);
static gboolean update_visual_bell_type (const char *value);
static gboolean update_num_workspaces (int value); static gboolean update_num_workspaces (int value);
static gboolean update_application_based (gboolean value); static gboolean update_application_based (gboolean value);
static gboolean update_disable_workarounds (gboolean value); static gboolean update_disable_workarounds (gboolean value);
@ -273,7 +282,7 @@ meta_prefs_init (void)
GError *err = NULL; GError *err = NULL;
char *str_val; char *str_val;
int int_val; int int_val;
gboolean bool_val; gboolean bool_val, bool_val_2;
if (default_client != NULL) if (default_client != NULL)
return; return;
@ -360,6 +369,20 @@ meta_prefs_init (void)
g_free (str_val); g_free (str_val);
#endif /* HAVE_GCONF */ #endif /* HAVE_GCONF */
bool_val = gconf_client_get_bool (default_client, KEY_VISUAL_BELL,
&err);
cleanup_error (&err);
bool_val_2 = gconf_client_get_bool (default_client, KEY_AUDIBLE_BELL,
&err);
cleanup_error (&err);
update_visual_bell (bool_val, bool_val_2);
str_val = gconf_client_get_string (default_client, KEY_VISUAL_BELL_TYPE,
&err);
cleanup_error (&err);
update_visual_bell_type (str_val);
g_free (str_val);
/* Load keybindings prefs */ /* Load keybindings prefs */
init_bindings (); init_bindings ();
@ -375,7 +398,7 @@ meta_prefs_init (void)
NULL, NULL,
NULL, NULL,
&err); &err);
cleanup_error (&err); cleanup_error (&err);
#endif /* HAVE_GCONF */ #endif /* HAVE_GCONF */
} }
@ -674,6 +697,37 @@ change_notify (GConfClient *client,
if (update_button_layout (str)) if (update_button_layout (str))
queue_changed (META_PREF_BUTTON_LAYOUT); queue_changed (META_PREF_BUTTON_LAYOUT);
} }
else if (strcmp (key, KEY_VISUAL_BELL) == 0)
{
gboolean b;
b = value ? gconf_value_get_bool (value) : provide_visual_bell;
if (update_visual_bell (b, bell_is_audible))
queue_changed (META_PREF_VISUAL_BELL);
}
else if (strcmp (key, KEY_AUDIBLE_BELL) == 0)
{
gboolean b;
b = value ? gconf_value_get_bool (value) : bell_is_audible;
if (update_visual_bell (provide_visual_bell, b))
queue_changed (META_PREF_AUDIBLE_BELL);
}
else if (strcmp (key, KEY_VISUAL_BELL_TYPE) == 0)
{
const char * str;
if (value && value->type != GCONF_VALUE_STRING)
{
meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
KEY_VISUAL_BELL_TYPE);
goto out;
}
str = value ? gconf_value_get_string (value) : NULL;
if (update_visual_bell_type (str))
queue_changed (META_PREF_VISUAL_BELL_TYPE);
}
else else
{ {
meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n", meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n",
@ -803,8 +857,48 @@ update_use_system_font (gboolean value)
return old != value; return old != value;
} }
static MetaVisualBellType
visual_bell_type_from_string (const char *value)
{
if (!strcmp (value, "fullscreen"))
{
return META_VISUAL_BELL_FULLSCREEN_FLASH;
}
else if (!strcmp (value, "frame_flash"))
{
return META_VISUAL_BELL_FRAME_FLASH;
}
return META_VISUAL_BELL_FULLSCREEN_FLASH;
}
static gboolean
update_visual_bell_type (const char *value)
{
MetaVisualBellType old_bell_type;
old_bell_type = visual_bell_type;
visual_bell_type = visual_bell_type_from_string (value);
return (visual_bell_type != old_bell_type);
}
#endif /* HAVE_GCONF */ #endif /* HAVE_GCONF */
static gboolean
update_visual_bell (gboolean visual_bell, gboolean audible_bell)
{
gboolean old_visual = provide_visual_bell;
gboolean old_audible = bell_is_audible;
gboolean has_changed;
provide_visual_bell = visual_bell;
bell_is_audible = audible_bell;
has_changed = (old_visual != provide_visual_bell) ||
(old_audible != bell_is_audible);
return has_changed;
}
#ifdef HAVE_GCONF #ifdef HAVE_GCONF
static gboolean static gboolean
update_titlebar_font (const char *value) update_titlebar_font (const char *value)
@ -1186,6 +1280,18 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_WORKSPACE_NAMES: case META_PREF_WORKSPACE_NAMES:
return "WORKSPACE_NAMES"; return "WORKSPACE_NAMES";
break; break;
case META_PREF_VISUAL_BELL:
return "VISUAL_BELL";
break;
case META_PREF_AUDIBLE_BELL:
return "AUDIBLE_BELL";
break;
case META_PREF_VISUAL_BELL_TYPE:
return "VISUAL_BELL_TYPE";
break;
} }
return "(unknown)"; return "(unknown)";
@ -1750,6 +1856,24 @@ meta_prefs_get_button_layout (MetaButtonLayout *button_layout_p)
*button_layout_p = button_layout; *button_layout_p = button_layout;
} }
gboolean
meta_prefs_get_visual_bell ()
{
return provide_visual_bell;
}
gboolean
meta_prefs_bell_is_audible ()
{
return bell_is_audible;
}
MetaVisualBellType
meta_prefs_get_visual_bell_type ()
{
return visual_bell_type;
}
void void
meta_prefs_get_screen_bindings (const MetaKeyPref **bindings, meta_prefs_get_screen_bindings (const MetaKeyPref **bindings,
int *n_bindings) int *n_bindings)

View File

@ -42,7 +42,10 @@ typedef enum
META_PREF_DISABLE_WORKAROUNDS, META_PREF_DISABLE_WORKAROUNDS,
META_PREF_COMMANDS, META_PREF_COMMANDS,
META_PREF_BUTTON_LAYOUT, META_PREF_BUTTON_LAYOUT,
META_PREF_WORKSPACE_NAMES META_PREF_WORKSPACE_NAMES,
META_PREF_VISUAL_BELL,
META_PREF_AUDIBLE_BELL,
META_PREF_VISUAL_BELL_TYPE
} MetaPreference; } MetaPreference;
typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
@ -213,6 +216,18 @@ void meta_prefs_get_window_binding (const char *name,
unsigned int *keysym, unsigned int *keysym,
MetaVirtualModifier *modifiers); MetaVirtualModifier *modifiers);
typedef enum
{
META_VISUAL_BELL_INVALID = 0,
META_VISUAL_BELL_FULLSCREEN_FLASH,
META_VISUAL_BELL_FRAME_FLASH
} MetaVisualBellType;
gboolean meta_prefs_get_visual_bell (void);
gboolean meta_prefs_bell_is_audible (void);
MetaVisualBellType meta_prefs_get_visual_bell_type (void);
#endif #endif

View File

@ -523,6 +523,7 @@ meta_screen_new (MetaDisplay *display,
screen->current_cursor = -1; /* invalid/unset */ screen->current_cursor = -1; /* invalid/unset */
screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen); screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen);
screen->default_depth = DefaultDepthOfScreen (screen->xscreen); screen->default_depth = DefaultDepthOfScreen (screen->xscreen);
screen->flash_window = None;
screen->wm_sn_selection_window = new_wm_sn_owner; screen->wm_sn_selection_window = new_wm_sn_owner;
screen->wm_sn_atom = wm_sn_atom; screen->wm_sn_atom = wm_sn_atom;

View File

@ -70,6 +70,8 @@ struct _MetaScreen
MetaCursor current_cursor; MetaCursor current_cursor;
Window flash_window;
Window wm_sn_selection_window; Window wm_sn_selection_window;
Atom wm_sn_atom; Atom wm_sn_atom;
Time wm_sn_timestamp; Time wm_sn_timestamp;

View File

@ -4760,8 +4760,10 @@ theme_get_style (MetaTheme *theme,
resize = META_FRAME_RESIZE_LAST; /* compiler */ resize = META_FRAME_RESIZE_LAST; /* compiler */
break; break;
} }
if (flags & META_FRAME_HAS_FOCUS) /* re invert the styles used for focus/unfocussed while flashing a frame */
if (((flags & META_FRAME_HAS_FOCUS) && !(flags & META_FRAME_IS_FLASHING))
|| (!(flags & META_FRAME_HAS_FOCUS) && (flags & META_FRAME_IS_FLASHING)))
focus = META_FRAME_FOCUS_YES; focus = META_FRAME_FOCUS_YES;
else else
focus = META_FRAME_FOCUS_NO; focus = META_FRAME_FOCUS_NO;