mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-25 14:05:41 -05:00
Set urgent WM flag on bell on X11 systems (#812)
Sets the urgent WM flag when bell is emitted on X11 systems. Additionally, the flag is cleared on focus because not all WMs clear it automatically.
This commit is contained in:
parent
b79574ee82
commit
f6f2bcd024
4 changed files with 61 additions and 0 deletions
|
@ -322,6 +322,14 @@ impl Display {
|
|||
self.window.set_title(&title);
|
||||
}
|
||||
|
||||
if let Some(is_urgent) = terminal.next_is_urgent.take() {
|
||||
// We don't need to set the urgent flag if we already have the
|
||||
// user's attention.
|
||||
if !is_urgent || !self.window.is_focused {
|
||||
self.window.set_urgent(is_urgent);
|
||||
}
|
||||
}
|
||||
|
||||
let size_info = *terminal.size_info();
|
||||
let visual_bell_intensity = terminal.visual_bell.intensity();
|
||||
|
||||
|
|
|
@ -251,6 +251,7 @@ impl<N: Notify> Processor<N> {
|
|||
ref_test: bool,
|
||||
resize_tx: &mpsc::Sender<(u32, u32)>,
|
||||
hide_cursor: &mut bool,
|
||||
window_is_focused: &mut bool,
|
||||
) {
|
||||
match event {
|
||||
// Pass on device events
|
||||
|
@ -322,8 +323,11 @@ impl<N: Notify> Processor<N> {
|
|||
processor.ctx.terminal.dirty = true;
|
||||
},
|
||||
Focused(is_focused) => {
|
||||
*window_is_focused = is_focused;
|
||||
|
||||
if is_focused {
|
||||
processor.ctx.terminal.dirty = true;
|
||||
processor.ctx.terminal.next_is_urgent = Some(false);
|
||||
} else {
|
||||
*hide_cursor = false;
|
||||
}
|
||||
|
@ -395,6 +399,8 @@ impl<N: Notify> Processor<N> {
|
|||
mouse_bindings: &self.mouse_bindings[..],
|
||||
};
|
||||
|
||||
let mut window_is_focused = window.is_focused;
|
||||
|
||||
// Scope needed to that hide_cursor isn't borrowed after the scope
|
||||
// ends.
|
||||
{
|
||||
|
@ -409,6 +415,7 @@ impl<N: Notify> Processor<N> {
|
|||
ref_test,
|
||||
resize_tx,
|
||||
hide_cursor,
|
||||
&mut window_is_focused,
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -423,6 +430,8 @@ impl<N: Notify> Processor<N> {
|
|||
window.set_cursor_visible(!self.hide_cursor);
|
||||
}
|
||||
|
||||
window.is_focused = window_is_focused;
|
||||
|
||||
if processor.ctx.selection_modified {
|
||||
processor.ctx.terminal.dirty = true;
|
||||
}
|
||||
|
|
|
@ -689,6 +689,7 @@ pub struct Term {
|
|||
pub dirty: bool,
|
||||
|
||||
pub visual_bell: VisualBell,
|
||||
pub next_is_urgent: Option<bool>,
|
||||
|
||||
/// Saved cursor from main grid
|
||||
cursor_save: Cursor,
|
||||
|
@ -791,6 +792,7 @@ impl Term {
|
|||
next_title: None,
|
||||
dirty: false,
|
||||
visual_bell: VisualBell::new(config),
|
||||
next_is_urgent: None,
|
||||
input_needs_wrap: false,
|
||||
grid: grid,
|
||||
alt_grid: alt,
|
||||
|
@ -1459,6 +1461,7 @@ impl ansi::Handler for Term {
|
|||
fn bell(&mut self) {
|
||||
trace!("bell");
|
||||
self.visual_bell.ring();
|
||||
self.next_is_urgent = Some(true);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -39,6 +39,9 @@ pub struct Window {
|
|||
event_loop: EventsLoop,
|
||||
window: glutin::GlWindow,
|
||||
cursor_visible: bool,
|
||||
|
||||
/// Whether or not the window is the focused window.
|
||||
pub is_focused: bool,
|
||||
}
|
||||
|
||||
/// Threadsafe APIs for the window
|
||||
|
@ -204,6 +207,7 @@ impl Window {
|
|||
event_loop: event_loop,
|
||||
window: window,
|
||||
cursor_visible: true,
|
||||
is_focused: true,
|
||||
};
|
||||
|
||||
window.run_os_extensions();
|
||||
|
@ -307,6 +311,43 @@ impl Window {
|
|||
pub fn platform_window_init() {
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
|
||||
pub fn set_urgent(&self, is_urgent: bool) {
|
||||
use glutin::os::unix::WindowExt;
|
||||
use std::os::raw;
|
||||
use x11_dl::xlib::{self, XUrgencyHint};
|
||||
|
||||
let xlib_display = self.window.get_xlib_display();
|
||||
let xlib_window = self.window.get_xlib_window();
|
||||
|
||||
if let (Some(xlib_window), Some(xlib_display)) = (xlib_window, xlib_display) {
|
||||
let xlib = xlib::Xlib::open().expect("get xlib");
|
||||
|
||||
unsafe {
|
||||
let mut hints = (xlib.XGetWMHints)(xlib_display as _, xlib_window as _);
|
||||
|
||||
if hints.is_null() {
|
||||
hints = (xlib.XAllocWMHints)();
|
||||
}
|
||||
|
||||
if is_urgent {
|
||||
(*hints).flags |= XUrgencyHint;
|
||||
} else {
|
||||
(*hints).flags &= !XUrgencyHint;
|
||||
}
|
||||
|
||||
(xlib.XSetWMHints)(xlib_display as _, xlib_window as _, hints);
|
||||
|
||||
(xlib.XFree)(hints as *mut raw::c_void);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd")))]
|
||||
pub fn set_urgent(&self, is_urgent: bool) {
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
|
||||
pub fn send_xim_spot(&self, x: i16, y: i16) {
|
||||
use glutin::os::unix::WindowExt;
|
||||
|
|
Loading…
Reference in a new issue