Make bell and libstartup-notification bits work without X11
https://bugzilla.gnome.org/show_bug.cgi?id=759538
This commit is contained in:
parent
8adab02757
commit
9333a6da75
130
src/core/bell.c
130
src/core/bell.c
@ -52,13 +52,73 @@
|
|||||||
#include "window-private.h"
|
#include "window-private.h"
|
||||||
#include "util-private.h"
|
#include "util-private.h"
|
||||||
#include "compositor/compositor-private.h"
|
#include "compositor/compositor-private.h"
|
||||||
#include "x11/meta-x11-display-private.h"
|
|
||||||
#include <meta/prefs.h>
|
|
||||||
#include <meta/compositor.h>
|
#include <meta/compositor.h>
|
||||||
#ifdef HAVE_LIBCANBERRA
|
#ifdef HAVE_LIBCANBERRA
|
||||||
#include <canberra-gtk.h>
|
#include <canberra-gtk.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MetaBell, meta_bell, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
IS_AUDIBLE_CHANGED,
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint bell_signals [LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
static void
|
||||||
|
prefs_changed_callback (MetaPreference pref,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
MetaBell *bell = data;
|
||||||
|
|
||||||
|
if (pref == META_PREF_AUDIBLE_BELL)
|
||||||
|
{
|
||||||
|
g_signal_emit (bell, bell_signals[IS_AUDIBLE_CHANGED], 0,
|
||||||
|
meta_prefs_bell_is_audible ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_bell_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
MetaBell *bell = META_BELL (object);
|
||||||
|
|
||||||
|
meta_prefs_remove_listener (prefs_changed_callback, bell);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (meta_bell_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_bell_class_init (MetaBellClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = meta_bell_finalize;
|
||||||
|
|
||||||
|
bell_signals[IS_AUDIBLE_CHANGED] =
|
||||||
|
g_signal_new ("is-audible-changed",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 1,
|
||||||
|
G_TYPE_BOOLEAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_bell_init (MetaBell *bell)
|
||||||
|
{
|
||||||
|
meta_prefs_add_listener (prefs_changed_callback, bell);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaBell *
|
||||||
|
meta_bell_new (MetaDisplay *display)
|
||||||
|
{
|
||||||
|
return g_object_new (META_TYPE_BELL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bell_flash_fullscreen:
|
* bell_flash_fullscreen:
|
||||||
* @display: The display the event came in on
|
* @display: The display the event came in on
|
||||||
@ -226,72 +286,6 @@ meta_bell_notify (MetaDisplay *display,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
meta_bell_set_audible (MetaDisplay *display, gboolean audible)
|
|
||||||
{
|
|
||||||
MetaX11Display *x11_display = display->x11_display;
|
|
||||||
#ifdef HAVE_LIBCANBERRA
|
|
||||||
/* When we are playing sounds using libcanberra support, we handle the
|
|
||||||
* bell whether its an audible bell or a visible bell */
|
|
||||||
gboolean enable_system_bell = FALSE;
|
|
||||||
#else
|
|
||||||
gboolean enable_system_bell = audible;
|
|
||||||
#endif /* HAVE_LIBCANBERRA */
|
|
||||||
|
|
||||||
XkbChangeEnabledControls (x11_display->xdisplay,
|
|
||||||
XkbUseCoreKbd,
|
|
||||||
XkbAudibleBellMask,
|
|
||||||
enable_system_bell ? XkbAudibleBellMask : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
meta_bell_init (MetaDisplay *display)
|
|
||||||
{
|
|
||||||
int xkb_base_error_type, xkb_opcode;
|
|
||||||
MetaX11Display *x11_display = display->x11_display;
|
|
||||||
|
|
||||||
if (!XkbQueryExtension (x11_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 (x11_display->xdisplay,
|
|
||||||
XkbUseCoreKbd,
|
|
||||||
XkbBellNotifyMask,
|
|
||||||
XkbBellNotifyMask);
|
|
||||||
meta_bell_set_audible (display, meta_prefs_bell_is_audible ());
|
|
||||||
if (visual_bell_auto_reset) {
|
|
||||||
XkbSetAutoResetControls (x11_display->xdisplay,
|
|
||||||
XkbAudibleBellMask,
|
|
||||||
&mask,
|
|
||||||
&mask);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_bell_shutdown (MetaDisplay *display)
|
|
||||||
{
|
|
||||||
MetaX11Display *x11_display = display->x11_display;
|
|
||||||
|
|
||||||
/* TODO: persist initial bell state in display, reset here */
|
|
||||||
XkbChangeEnabledControls (x11_display->xdisplay,
|
|
||||||
XkbUseCoreKbd,
|
|
||||||
XkbAudibleBellMask,
|
|
||||||
XkbAudibleBellMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_bell_notify_frame_destroy:
|
* meta_bell_notify_frame_destroy:
|
||||||
* @frame: The frame which is being destroyed
|
* @frame: The frame which is being destroyed
|
||||||
|
@ -17,11 +17,19 @@
|
|||||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/XKBlib.h>
|
|
||||||
#include "display-private.h"
|
#include "display-private.h"
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
|
|
||||||
|
struct _MetaBell
|
||||||
|
{
|
||||||
|
GObject parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define META_TYPE_BELL (meta_bell_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaBell, meta_bell, META, BELL, GObject)
|
||||||
|
|
||||||
|
MetaBell * meta_bell_new (MetaDisplay *display);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_bell_notify:
|
* meta_bell_notify:
|
||||||
* @display: The display the bell event came in on
|
* @display: The display the bell event came in on
|
||||||
@ -34,48 +42,6 @@
|
|||||||
gboolean meta_bell_notify (MetaDisplay *display,
|
gboolean meta_bell_notify (MetaDisplay *display,
|
||||||
MetaWindow *window);
|
MetaWindow *window);
|
||||||
|
|
||||||
/**
|
|
||||||
* meta_bell_set_audible:
|
|
||||||
* @display: The display we're configuring
|
|
||||||
* @audible: True for an audible bell, false for a visual bell
|
|
||||||
*
|
|
||||||
* Turns the bell to audible or visual. This tells X what to do, but
|
|
||||||
* not Mutter; you will need to set the "visual bell" pref for that.
|
|
||||||
*
|
|
||||||
* If the configure script found we had no XKB, this is a no-op.
|
|
||||||
*/
|
|
||||||
void meta_bell_set_audible (MetaDisplay *display, gboolean audible);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* meta_bell_init:
|
|
||||||
* @display: The display which is opening
|
|
||||||
*
|
|
||||||
* Initialises the bell subsystem. This involves intialising
|
|
||||||
* XKB (which, despite being a keyboard extension, is the
|
|
||||||
* place to look for bell notifications), then asking it
|
|
||||||
* to send us bell notifications, and then also switching
|
|
||||||
* off the audible bell if we're using a visual one ourselves.
|
|
||||||
*
|
|
||||||
* \bug There is a line of code that's never run that tells
|
|
||||||
* XKB to reset the bell status after we quit. Bill H said
|
|
||||||
* (<http://bugzilla.gnome.org/show_bug.cgi?id=99886#c12>)
|
|
||||||
* that XFree86's implementation is broken so we shouldn't
|
|
||||||
* call it, but that was in 2002. Is it working now?
|
|
||||||
*/
|
|
||||||
gboolean meta_bell_init (MetaDisplay *display);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* meta_bell_shutdown:
|
|
||||||
* @display: The display which is closing
|
|
||||||
*
|
|
||||||
* Shuts down the bell subsystem.
|
|
||||||
*
|
|
||||||
* \bug This is never called! If we had XkbSetAutoResetControls
|
|
||||||
* enabled in meta_bell_init(), this wouldn't be a problem, but
|
|
||||||
* we don't.
|
|
||||||
*/
|
|
||||||
void meta_bell_shutdown (MetaDisplay *display);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_bell_notify_frame_destroy:
|
* meta_bell_notify_frame_destroy:
|
||||||
* @frame: The frame which is being destroyed
|
* @frame: The frame which is being destroyed
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#include <X11/extensions/sync.h>
|
#include <X11/extensions/sync.h>
|
||||||
|
|
||||||
|
typedef struct _MetaBell MetaBell;
|
||||||
typedef struct _MetaStack MetaStack;
|
typedef struct _MetaStack MetaStack;
|
||||||
typedef struct _MetaUISlave MetaUISlave;
|
typedef struct _MetaUISlave MetaUISlave;
|
||||||
|
|
||||||
@ -205,9 +206,6 @@ struct _MetaDisplay
|
|||||||
* to avoid some race conditions on EnterNotify events
|
* to avoid some race conditions on EnterNotify events
|
||||||
*/
|
*/
|
||||||
int sentinel_counter;
|
int sentinel_counter;
|
||||||
|
|
||||||
int xkb_base_event_type;
|
|
||||||
guint32 last_bell_time;
|
|
||||||
int grab_resize_timeout_id;
|
int grab_resize_timeout_id;
|
||||||
|
|
||||||
MetaKeyBindingManager key_binding_manager;
|
MetaKeyBindingManager key_binding_manager;
|
||||||
@ -254,6 +252,8 @@ struct _MetaDisplay
|
|||||||
MetaDisplayCorner starting_corner;
|
MetaDisplayCorner starting_corner;
|
||||||
guint vertical_workspaces : 1;
|
guint vertical_workspaces : 1;
|
||||||
guint workspace_layout_overridden : 1;
|
guint workspace_layout_overridden : 1;
|
||||||
|
|
||||||
|
MetaBell *bell;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaDisplayClass
|
struct _MetaDisplayClass
|
||||||
|
@ -765,7 +765,6 @@ meta_display_open (void)
|
|||||||
|
|
||||||
display->grab_resize_timeout_id = 0;
|
display->grab_resize_timeout_id = 0;
|
||||||
display->grab_have_keyboard = FALSE;
|
display->grab_have_keyboard = FALSE;
|
||||||
display->last_bell_time = 0;
|
|
||||||
|
|
||||||
display->grab_op = META_GRAB_OP_NONE;
|
display->grab_op = META_GRAB_OP_NONE;
|
||||||
display->grab_window = NULL;
|
display->grab_window = NULL;
|
||||||
@ -804,7 +803,6 @@ meta_display_open (void)
|
|||||||
|
|
||||||
meta_display_set_cursor (display, META_CURSOR_DEFAULT);
|
meta_display_set_cursor (display, META_CURSOR_DEFAULT);
|
||||||
|
|
||||||
|
|
||||||
/* This is the default layout extracted from default
|
/* This is the default layout extracted from default
|
||||||
* variable values in update_num_workspaces ()
|
* variable values in update_num_workspaces ()
|
||||||
* This can be overriden using _NET_DESKTOP_LAYOUT in
|
* This can be overriden using _NET_DESKTOP_LAYOUT in
|
||||||
@ -824,6 +822,12 @@ meta_display_open (void)
|
|||||||
|
|
||||||
reload_logical_monitors (display);
|
reload_logical_monitors (display);
|
||||||
|
|
||||||
|
display->startup_notification = meta_startup_notification_get (display);
|
||||||
|
g_signal_connect (display->startup_notification, "changed",
|
||||||
|
G_CALLBACK (on_startup_notification_changed), display);
|
||||||
|
|
||||||
|
display->bell = meta_bell_new (display);
|
||||||
|
|
||||||
x11_display = meta_x11_display_new (display, &error);
|
x11_display = meta_x11_display_new (display, &error);
|
||||||
g_assert (x11_display != NULL); /* Required, for now */
|
g_assert (x11_display != NULL); /* Required, for now */
|
||||||
display->x11_display = x11_display;
|
display->x11_display = x11_display;
|
||||||
@ -834,8 +838,6 @@ meta_display_open (void)
|
|||||||
display->stack = meta_stack_new (display);
|
display->stack = meta_stack_new (display);
|
||||||
display->stack_tracker = meta_stack_tracker_new (display);
|
display->stack_tracker = meta_stack_tracker_new (display);
|
||||||
|
|
||||||
meta_bell_init (display);
|
|
||||||
|
|
||||||
display->last_focus_time = timestamp;
|
display->last_focus_time = timestamp;
|
||||||
display->last_user_time = timestamp;
|
display->last_user_time = timestamp;
|
||||||
display->compositor = NULL;
|
display->compositor = NULL;
|
||||||
@ -846,10 +848,6 @@ meta_display_open (void)
|
|||||||
display->x11_display->atom__NET_ACTIVE_WINDOW,
|
display->x11_display->atom__NET_ACTIVE_WINDOW,
|
||||||
&old_active_xwindow);
|
&old_active_xwindow);
|
||||||
|
|
||||||
display->startup_notification = meta_startup_notification_get (display);
|
|
||||||
g_signal_connect (display->startup_notification, "changed",
|
|
||||||
G_CALLBACK (on_startup_notification_changed), display);
|
|
||||||
|
|
||||||
enable_compositor (display);
|
enable_compositor (display);
|
||||||
|
|
||||||
if (display->x11_display)
|
if (display->x11_display)
|
||||||
@ -1015,7 +1013,6 @@ meta_display_close (MetaDisplay *display,
|
|||||||
|
|
||||||
meta_display_remove_autoraise_callback (display);
|
meta_display_remove_autoraise_callback (display);
|
||||||
|
|
||||||
g_clear_object (&display->startup_notification);
|
|
||||||
g_clear_object (&display->gesture_tracker);
|
g_clear_object (&display->gesture_tracker);
|
||||||
|
|
||||||
g_clear_pointer (&display->stack, (GDestroyNotify) meta_stack_free);
|
g_clear_pointer (&display->stack, (GDestroyNotify) meta_stack_free);
|
||||||
@ -1056,6 +1053,9 @@ meta_display_close (MetaDisplay *display,
|
|||||||
|
|
||||||
meta_display_shutdown_keys (display);
|
meta_display_shutdown_keys (display);
|
||||||
|
|
||||||
|
g_clear_object (&display->bell);
|
||||||
|
g_clear_object (&display->startup_notification);
|
||||||
|
|
||||||
g_object_unref (display);
|
g_object_unref (display);
|
||||||
the_display = NULL;
|
the_display = NULL;
|
||||||
|
|
||||||
@ -2564,11 +2564,7 @@ prefs_changed_callback (MetaPreference pref,
|
|||||||
{
|
{
|
||||||
MetaDisplay *display = data;
|
MetaDisplay *display = data;
|
||||||
|
|
||||||
if (pref == META_PREF_AUDIBLE_BELL)
|
if (pref == META_PREF_CURSOR_THEME ||
|
||||||
{
|
|
||||||
meta_bell_set_audible (display, meta_prefs_bell_is_audible ());
|
|
||||||
}
|
|
||||||
else if (pref == META_PREF_CURSOR_THEME ||
|
|
||||||
pref == META_PREF_CURSOR_SIZE)
|
pref == META_PREF_CURSOR_SIZE)
|
||||||
{
|
{
|
||||||
meta_display_reload_cursor (display);
|
meta_display_reload_cursor (display);
|
||||||
|
@ -528,11 +528,6 @@ meta_startup_notification_finalize (GObject *object)
|
|||||||
{
|
{
|
||||||
MetaStartupNotification *sn = META_STARTUP_NOTIFICATION (object);
|
MetaStartupNotification *sn = META_STARTUP_NOTIFICATION (object);
|
||||||
|
|
||||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
|
||||||
sn_monitor_context_unref (sn->sn_context);
|
|
||||||
sn_display_unref (sn->sn_display);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (sn->startup_sequence_timeout)
|
if (sn->startup_sequence_timeout)
|
||||||
g_source_remove (sn->startup_sequence_timeout);
|
g_source_remove (sn->startup_sequence_timeout);
|
||||||
|
|
||||||
@ -660,6 +655,33 @@ meta_startup_notification_sn_event (SnMonitorEvent *event,
|
|||||||
|
|
||||||
sn_startup_sequence_unref (sequence);
|
sn_startup_sequence_unref (sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_x11_display_opened (MetaStartupNotification *sn)
|
||||||
|
{
|
||||||
|
MetaX11Display *x11_display = sn->display->x11_display;
|
||||||
|
|
||||||
|
sn->sn_display = sn_display_new (x11_display->xdisplay,
|
||||||
|
sn_error_trap_push,
|
||||||
|
sn_error_trap_pop);
|
||||||
|
|
||||||
|
sn->sn_context =
|
||||||
|
sn_monitor_context_new (sn->sn_display,
|
||||||
|
meta_x11_display_get_screen_number (x11_display),
|
||||||
|
meta_startup_notification_sn_event,
|
||||||
|
sn,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_x11_display_closing (MetaStartupNotification *sn)
|
||||||
|
{
|
||||||
|
sn_monitor_context_unref (sn->sn_context);
|
||||||
|
sn->sn_context = NULL;
|
||||||
|
|
||||||
|
sn_display_unref (sn->sn_display);
|
||||||
|
sn->sn_display = NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -670,16 +692,22 @@ meta_startup_notification_constructed (GObject *object)
|
|||||||
g_assert (sn->display != NULL);
|
g_assert (sn->display != NULL);
|
||||||
|
|
||||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||||
sn->sn_display = sn_display_new (sn->display->x11_display->xdisplay,
|
sn->sn_display = NULL;
|
||||||
sn_error_trap_push,
|
sn->sn_context = NULL;
|
||||||
sn_error_trap_pop);
|
|
||||||
sn->sn_context =
|
g_signal_connect_object (sn->display,
|
||||||
sn_monitor_context_new (sn->sn_display,
|
"x11-display-opened",
|
||||||
meta_ui_get_screen_number (),
|
G_CALLBACK (on_x11_display_opened),
|
||||||
meta_startup_notification_sn_event,
|
|
||||||
sn,
|
sn,
|
||||||
NULL);
|
G_CONNECT_SWAPPED);
|
||||||
|
|
||||||
|
g_signal_connect_object (sn->display,
|
||||||
|
"x11-display-closing",
|
||||||
|
G_CALLBACK (on_x11_display_closing),
|
||||||
|
sn,
|
||||||
|
G_CONNECT_SWAPPED);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sn->startup_sequences = NULL;
|
sn->startup_sequences = NULL;
|
||||||
sn->startup_sequence_timeout = 0;
|
sn->startup_sequence_timeout = 0;
|
||||||
}
|
}
|
||||||
@ -753,6 +781,9 @@ meta_startup_notification_get_sequences (MetaStartupNotification *sn)
|
|||||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||||
GSList *l;
|
GSList *l;
|
||||||
|
|
||||||
|
if (!sn->sn_display)
|
||||||
|
return sequences;
|
||||||
|
|
||||||
/* We return a list of SnStartupSequences here */
|
/* We return a list of SnStartupSequences here */
|
||||||
for (l = sn->startup_sequences; l; l = l->next)
|
for (l = sn->startup_sequences; l; l = l->next)
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "x11/events.h"
|
#include "x11/events.h"
|
||||||
|
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
#include <X11/extensions/Xdamage.h>
|
#include <X11/extensions/Xdamage.h>
|
||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
|
|
||||||
@ -1166,23 +1167,24 @@ process_selection_clear (MetaX11Display *x11_display,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
notify_bell (MetaDisplay *display,
|
notify_bell (MetaX11Display *x11_display,
|
||||||
XkbAnyEvent *xkb_ev)
|
XkbAnyEvent *xkb_ev)
|
||||||
{
|
{
|
||||||
|
MetaDisplay *display = x11_display->display;
|
||||||
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent*) xkb_ev;
|
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent*) xkb_ev;
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
|
|
||||||
window = meta_x11_display_lookup_x_window (display->x11_display,
|
window = meta_x11_display_lookup_x_window (x11_display,
|
||||||
xkb_bell_event->window);
|
xkb_bell_event->window);
|
||||||
if (!window && display->focus_window && display->focus_window->frame)
|
if (!window && display->focus_window && display->focus_window->frame)
|
||||||
window = display->focus_window;
|
window = display->focus_window;
|
||||||
|
|
||||||
display->last_bell_time = xkb_ev->time;
|
x11_display->last_bell_time = xkb_ev->time;
|
||||||
if (!meta_bell_notify (display, window) &&
|
if (!meta_bell_notify (display, window) &&
|
||||||
meta_prefs_bell_is_audible ())
|
meta_prefs_bell_is_audible ())
|
||||||
{
|
{
|
||||||
/* Force a classic bell if the libcanberra bell failed. */
|
/* Force a classic bell if the libcanberra bell failed. */
|
||||||
XkbForceDeviceBell (display->x11_display->xdisplay,
|
XkbForceDeviceBell (x11_display->xdisplay,
|
||||||
xkb_bell_event->device,
|
xkb_bell_event->device,
|
||||||
xkb_bell_event->bell_class,
|
xkb_bell_event->bell_class,
|
||||||
xkb_bell_event->bell_id,
|
xkb_bell_event->bell_id,
|
||||||
@ -1656,17 +1658,17 @@ handle_other_xevent (MetaX11Display *x11_display,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (event->type == display->xkb_base_event_type)
|
if (event->type == x11_display->xkb_base_event_type)
|
||||||
{
|
{
|
||||||
XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;
|
XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;
|
||||||
|
|
||||||
switch (xkb_ev->xkb_type)
|
switch (xkb_ev->xkb_type)
|
||||||
{
|
{
|
||||||
case XkbBellNotify:
|
case XkbBellNotify:
|
||||||
if (XSERVER_TIME_IS_BEFORE(display->last_bell_time,
|
if (XSERVER_TIME_IS_BEFORE(x11_display->last_bell_time,
|
||||||
xkb_ev->time - 100))
|
xkb_ev->time - 100))
|
||||||
{
|
{
|
||||||
notify_bell (display, xkb_ev);
|
notify_bell (x11_display, xkb_ev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -110,6 +110,9 @@ struct _MetaX11Display
|
|||||||
/* Managed by group-props.c */
|
/* Managed by group-props.c */
|
||||||
MetaGroupPropHooks *group_prop_hooks;
|
MetaGroupPropHooks *group_prop_hooks;
|
||||||
|
|
||||||
|
int xkb_base_event_type;
|
||||||
|
guint32 last_bell_time;
|
||||||
|
|
||||||
MetaAlarmFilter alarm_filter;
|
MetaAlarmFilter alarm_filter;
|
||||||
gpointer alarm_filter_data;
|
gpointer alarm_filter_data;
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
#ifdef HAVE_RANDR
|
#ifdef HAVE_RANDR
|
||||||
#include <X11/extensions/Xrandr.h>
|
#include <X11/extensions/Xrandr.h>
|
||||||
#endif
|
#endif
|
||||||
@ -402,6 +403,97 @@ query_xi_extension (MetaX11Display *x11_display)
|
|||||||
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
|
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialises the bell subsystem. This involves intialising
|
||||||
|
* XKB (which, despite being a keyboard extension, is the
|
||||||
|
* place to look for bell notifications), then asking it
|
||||||
|
* to send us bell notifications, and then also switching
|
||||||
|
* off the audible bell if we're using a visual one ourselves.
|
||||||
|
*
|
||||||
|
* \bug There is a line of code that's never run that tells
|
||||||
|
* XKB to reset the bell status after we quit. Bill H said
|
||||||
|
* (<http://bugzilla.gnome.org/show_bug.cgi?id=99886#c12>)
|
||||||
|
* that XFree86's implementation is broken so we shouldn't
|
||||||
|
* call it, but that was in 2002. Is it working now?
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
init_x11_bell (MetaX11Display *x11_display)
|
||||||
|
{
|
||||||
|
int xkb_base_error_type, xkb_opcode;
|
||||||
|
|
||||||
|
if (!XkbQueryExtension (x11_display->xdisplay, &xkb_opcode,
|
||||||
|
&x11_display->xkb_base_event_type,
|
||||||
|
&xkb_base_error_type,
|
||||||
|
NULL, NULL))
|
||||||
|
{
|
||||||
|
x11_display->xkb_base_event_type = -1;
|
||||||
|
meta_warning ("could not find XKB extension.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int mask = XkbBellNotifyMask;
|
||||||
|
gboolean visual_bell_auto_reset = FALSE;
|
||||||
|
/* TRUE if and when non-broken version is available */
|
||||||
|
XkbSelectEvents (x11_display->xdisplay,
|
||||||
|
XkbUseCoreKbd,
|
||||||
|
XkbBellNotifyMask,
|
||||||
|
XkbBellNotifyMask);
|
||||||
|
|
||||||
|
if (visual_bell_auto_reset)
|
||||||
|
{
|
||||||
|
XkbSetAutoResetControls (x11_display->xdisplay,
|
||||||
|
XkbAudibleBellMask,
|
||||||
|
&mask,
|
||||||
|
&mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \bug This is never called! If we had XkbSetAutoResetControls
|
||||||
|
* enabled in meta_x11_bell_init(), this wouldn't be a problem,
|
||||||
|
* but we don't.
|
||||||
|
*/
|
||||||
|
G_GNUC_UNUSED static void
|
||||||
|
shutdown_x11_bell (MetaX11Display *x11_display)
|
||||||
|
{
|
||||||
|
/* TODO: persist initial bell state in display, reset here */
|
||||||
|
XkbChangeEnabledControls (x11_display->xdisplay,
|
||||||
|
XkbUseCoreKbd,
|
||||||
|
XkbAudibleBellMask,
|
||||||
|
XkbAudibleBellMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Turns the bell to audible or visual. This tells X what to do, but
|
||||||
|
* not Mutter; you will need to set the "visual bell" pref for that.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
set_x11_bell_is_audible (MetaX11Display *x11_display,
|
||||||
|
gboolean is_audible)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LIBCANBERRA
|
||||||
|
/* When we are playing sounds using libcanberra support, we handle the
|
||||||
|
* bell whether its an audible bell or a visible bell */
|
||||||
|
gboolean enable_system_bell = FALSE;
|
||||||
|
#else
|
||||||
|
gboolean enable_system_bell = is_audible;
|
||||||
|
#endif /* HAVE_LIBCANBERRA */
|
||||||
|
|
||||||
|
XkbChangeEnabledControls (x11_display->xdisplay,
|
||||||
|
XkbUseCoreKbd,
|
||||||
|
XkbAudibleBellMask,
|
||||||
|
enable_system_bell ? XkbAudibleBellMask : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_is_audible_changed (MetaBell *bell,
|
||||||
|
gboolean is_audible,
|
||||||
|
MetaX11Display *x11_display)
|
||||||
|
{
|
||||||
|
set_x11_bell_is_audible (x11_display, is_audible);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_desktop_geometry_hint (MetaX11Display *x11_display)
|
set_desktop_geometry_hint (MetaX11Display *x11_display)
|
||||||
{
|
{
|
||||||
@ -957,6 +1049,7 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
|
|||||||
x11_display->timestamp_pinging_window = None;
|
x11_display->timestamp_pinging_window = None;
|
||||||
x11_display->wm_sn_selection_window = None;
|
x11_display->wm_sn_selection_window = None;
|
||||||
|
|
||||||
|
x11_display->last_bell_time = 0;
|
||||||
x11_display->focus_serial = 0;
|
x11_display->focus_serial = 0;
|
||||||
x11_display->server_focus_window = None;
|
x11_display->server_focus_window = None;
|
||||||
x11_display->server_focus_serial = 0;
|
x11_display->server_focus_serial = 0;
|
||||||
@ -1105,6 +1198,14 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
|
|||||||
|
|
||||||
meta_prefs_add_listener (prefs_changed_callback, x11_display);
|
meta_prefs_add_listener (prefs_changed_callback, x11_display);
|
||||||
|
|
||||||
|
init_x11_bell (x11_display);
|
||||||
|
|
||||||
|
g_signal_connect_object (display->bell, "is-audible-changed",
|
||||||
|
G_CALLBACK (on_is_audible_changed),
|
||||||
|
x11_display, 0);
|
||||||
|
|
||||||
|
set_x11_bell_is_audible (x11_display, meta_prefs_bell_is_audible ());
|
||||||
|
|
||||||
return x11_display;
|
return x11_display;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user