Re: Visual bell
- From: Bill Haneman <bill haneman sun com>
- To: Havoc Pennington <hp redhat com>
- Cc: desktop-devel-list gnome org, otaylor redhat com
- Subject: Re: Visual bell
- Date: 21 Oct 2002 10:28:59 +0100
On Fri, 2002-10-18 at 19:24, Havoc Pennington wrote:
>
> Bill Haneman <bill haneman sun com> writes:
> > My guess is that since the window-border flashing is an obvious
> > possibility, and any app can flash the screen (by posting a big window
> > and then unposting it), the most likely candidate is Metacity.
> >
> > What do you think, Havoc? I can probably provide a patch for this, with
> > conditional compilation so that Metacity doesn't have to depend on XKB.
> > However I think you would be the right person to decide how a
> > "window-decoration-centric" visual bell feature should look and be
> > implemented in Metacity.
> >
>
> Sure, it sounds fine to me. We just need to get it spec'd out how the
> WM knows to display a bell. i.e. does metacity listen for some Xkb
> signal, or do we need to add a client message and support it in
> gdk_beep(), or what.
The best approach (works for all apps and toolkits on an X desktop) is
to listen for XkbBellNotify. It probably should be user-configurable as
to whether Metacity silences the 'audible bell' at the same time (by
setting XkbAudibleBellMask to 0 in a call to XkbChangeEnabledControls).
Also it should be user-configurable as to what the visual bell does; I
suggest the following options for starters:
1) flash the screen;
2) flash the toplevel-window border of the window that sent the bell.
#2 could be implemented (initially) as just a toggle between focussed
and unfocussed window visuals, and back. That would skirt the issues
below having to do with how a window border is "flashed". Note that the
XkbBellNotify events have a "window" parameter that allows you to
determine the origin of the bell (I suppose it could be 'None' in some
cases, in which case perhaps the currently-focussed window or the
topmost window could be flashed).
I attach a small C program that implements #1 above, as a standalone
program. I tried doing this in GTK+/GDK, so that I could make a
Metacity patch, but it appears that GTK+ keeps XKB events to itself, by
and large, and thus they are not available to a GdkFilterFunc (see
gdkevents-x11.c). Perhaps you and Owen could agree to a small GDK patch
that would propagate XKB events to filter-clients, in which case you
could trap them in Metacity's filterfunc. Otherwise, you will have to
open your own connection to the XServer :-(
Best regards,
Bill
> If you want to flash window borders, ideally we could think of a way
> to do this in a theme-agnostic fashion (such as lightening the whole
> border, or something); otherwise we'll need to break the theme format
> to require themes to explicitly define a "flash on" state. The
> problem here is knowing which window to flash, though. (Unless you
> want to flash them all, but that seems bizarre.)
>
> Havoc
>
/*
* AT-SPI - Assistive Technology Service Provider Interface
* (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
*
* Copyright 2001, 2002 Sun Microsystems Inc.,
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
static Display *display;
static Window flash_window = None;
static void
visual_bell_notify (XkbAnyEvent *xkb_ev)
{
Window root;
int width, height;
root = RootWindow (display, DefaultScreen (display));
width = DisplayWidth (display, DefaultScreen (display));
height = DisplayHeight (display, DefaultScreen (display));
if (flash_window == None)
{
flash_window = XCreateSimpleWindow (display, root,
0, 0, width, height,
0, 0L, 0L);
XSelectInput (display, flash_window, ExposureMask);
XMapWindow (display, flash_window);
}
else
{
/* just draw something in the window */
GC gc = XCreateGC (display, flash_window, 0, NULL);
XSetForeground (display, gc,
WhitePixel (display, DefaultScreen (display)));
XFillRectangle (display, flash_window, gc,
0, 0, width, height);
XSetForeground (display, gc,
BlackPixel (display, DefaultScreen (display)));
XFillRectangle (display, flash_window, gc,
0, 0, width, height);
}
XFlush (display);
}
int main (int argc, char **argv)
{
XEvent xev;
int ir, xkb_base_event_type, reason_return;
char *display_name = getenv ("DISPLAY");
if (!display_name) display_name = ":0.0";
display = XkbOpenDisplay (display_name,
&xkb_base_event_type,
&ir, NULL, NULL, &reason_return);
if (!display)
{
fprintf (stderr, "Could not connect to display! (%d)\n",
reason_return);
exit (-1);
}
XkbSelectEvents (display,
XkbUseCoreKbd,
XkbBellNotifyMask,
XkbBellNotifyMask);
/* comment this out to prevent bell on startup */
XkbBell (display, None, 100, None);
while (1)
{
XNextEvent (display, &xev);
if (xev.type == Expose)
{
XExposeEvent *exev = (XExposeEvent *) &xev;
if (exev->window == flash_window)
{
XDestroyWindow (display, flash_window);
flash_window = None;
/* discard pending bells */
XSync (display, True);
XFlush (display);
}
}
else if (xev.type == xkb_base_event_type)
{
XkbAnyEvent *xkb_ev = (XkbAnyEvent *) &xev;
switch (xkb_ev->xkb_type)
{
case XkbBellNotify:
/* flash something */
visual_bell_notify (xkb_ev);
break;
default:
}
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]