Prevent espanso crash when an X11 exception occurs. Fix #312
This commit is contained in:
parent
34c0a52455
commit
6766d91af3
|
@ -77,14 +77,20 @@ xdo_t * xdo_context;
|
||||||
|
|
||||||
// Callback invoked when a new key event occur.
|
// Callback invoked when a new key event occur.
|
||||||
void event_callback (XPointer, XRecordInterceptData*);
|
void event_callback (XPointer, XRecordInterceptData*);
|
||||||
|
int error_callback(Display *display, XErrorEvent *error);
|
||||||
|
|
||||||
KeypressCallback keypress_callback;
|
KeypressCallback keypress_callback;
|
||||||
|
X11ErrorCallback x11_error_callback;
|
||||||
void * context_instance;
|
void * context_instance;
|
||||||
|
|
||||||
void register_keypress_callback(KeypressCallback callback) {
|
void register_keypress_callback(KeypressCallback callback) {
|
||||||
keypress_callback = callback;
|
keypress_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void register_error_callback(X11ErrorCallback callback) {
|
||||||
|
x11_error_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t check_x11() {
|
int32_t check_x11() {
|
||||||
Display *check_disp = XOpenDisplay(NULL);
|
Display *check_disp = XOpenDisplay(NULL);
|
||||||
|
|
||||||
|
@ -156,6 +162,9 @@ int32_t initialize(void * _context_instance) {
|
||||||
|
|
||||||
xdo_context = xdo_new(NULL);
|
xdo_context = xdo_new(NULL);
|
||||||
|
|
||||||
|
// Setup a custom error handler
|
||||||
|
XSetErrorHandler(&error_callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: We might never get a MappingNotify event if the
|
* Note: We might never get a MappingNotify event if the
|
||||||
* modifier and keymap information was never cached in Xlib.
|
* modifier and keymap information was never cached in Xlib.
|
||||||
|
@ -272,6 +281,11 @@ void event_callback(XPointer p, XRecordInterceptData *hook)
|
||||||
XRecordFreeData(hook);
|
XRecordFreeData(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int error_callback(Display *display, XErrorEvent *error) {
|
||||||
|
x11_error_callback(context_instance, error->error_code, error->request_code, error->minor_code);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void release_all_keys() {
|
void release_all_keys() {
|
||||||
char keys[32];
|
char keys[32];
|
||||||
XQueryKeymap(xdo_context->xdpy, keys); // Get the current status of the keyboard
|
XQueryKeymap(xdo_context->xdpy, keys); // Get the current status of the keyboard
|
||||||
|
|
|
@ -49,7 +49,6 @@ extern "C" void cleanup();
|
||||||
* while the second is the size of the array.
|
* while the second is the size of the array.
|
||||||
*/
|
*/
|
||||||
typedef void (*KeypressCallback)(void * self, const char *buffer, int32_t len, int32_t event_type, int32_t key_code);
|
typedef void (*KeypressCallback)(void * self, const char *buffer, int32_t len, int32_t event_type, int32_t key_code);
|
||||||
|
|
||||||
extern KeypressCallback keypress_callback;
|
extern KeypressCallback keypress_callback;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -57,6 +56,17 @@ extern KeypressCallback keypress_callback;
|
||||||
*/
|
*/
|
||||||
extern "C" void register_keypress_callback(KeypressCallback callback);
|
extern "C" void register_keypress_callback(KeypressCallback callback);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called when a X11 error occurs
|
||||||
|
*/
|
||||||
|
typedef void (*X11ErrorCallback)(void * self, char error_code, char request_code, char minor_code);
|
||||||
|
extern X11ErrorCallback x11_error_callback;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register the callback that will be called when an X11 error occurs
|
||||||
|
*/
|
||||||
|
extern "C" void register_error_callback(X11ErrorCallback callback);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Type the given string by simulating Key Presses
|
* Type the given string by simulating Key Presses
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -32,6 +32,9 @@ extern "C" {
|
||||||
pub fn get_active_window_class(buffer: *mut c_char, size: i32) -> i32;
|
pub fn get_active_window_class(buffer: *mut c_char, size: i32) -> i32;
|
||||||
pub fn get_active_window_executable(buffer: *mut c_char, size: i32) -> i32;
|
pub fn get_active_window_executable(buffer: *mut c_char, size: i32) -> i32;
|
||||||
pub fn is_current_window_special() -> i32;
|
pub fn is_current_window_special() -> i32;
|
||||||
|
pub fn register_error_callback(
|
||||||
|
cb: extern "C" fn(_self: *mut c_void, error_code: c_char, request_code: c_char, minor_code: c_char),
|
||||||
|
);
|
||||||
|
|
||||||
// Keyboard
|
// Keyboard
|
||||||
pub fn register_keypress_callback(
|
pub fn register_keypress_callback(
|
||||||
|
|
|
@ -21,7 +21,7 @@ use crate::bridge::linux::*;
|
||||||
use crate::config::Configs;
|
use crate::config::Configs;
|
||||||
use crate::event::KeyModifier::*;
|
use crate::event::KeyModifier::*;
|
||||||
use crate::event::*;
|
use crate::event::*;
|
||||||
use log::{debug, error};
|
use log::{debug, error, warn};
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::os::raw::{c_char, c_void};
|
use std::os::raw::{c_char, c_void};
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
@ -59,6 +59,7 @@ impl LinuxContext {
|
||||||
let context_ptr = &*context as *const LinuxContext as *const c_void;
|
let context_ptr = &*context as *const LinuxContext as *const c_void;
|
||||||
|
|
||||||
register_keypress_callback(keypress_callback);
|
register_keypress_callback(keypress_callback);
|
||||||
|
register_error_callback(error_callback);
|
||||||
|
|
||||||
let res = initialize(context_ptr);
|
let res = initialize(context_ptr);
|
||||||
if res <= 0 {
|
if res <= 0 {
|
||||||
|
@ -155,3 +156,12 @@ extern "C" fn keypress_callback(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" fn error_callback(
|
||||||
|
_self: *mut c_void,
|
||||||
|
error_code: c_char,
|
||||||
|
request_code: c_char,
|
||||||
|
minor_code: c_char,
|
||||||
|
) {
|
||||||
|
warn!("X11 reported an error code: {}, request_code: {} and minor_code: {}", error_code, request_code, minor_code);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user