seat: allow session-switching with keyboard
This adds two new grabs to switch sessions within kmscon. They are set to ctrl+alt+Left/Right by default. To improve debugging, we also add some log-messages to session management. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
parent
22e63dbdba
commit
488f7abac0
@ -103,14 +103,18 @@ static void print_help()
|
||||
"\t --xkb-repeat-rate <msecs> [50]\n"
|
||||
"\t Delay between two key-repeats in ms\n"
|
||||
"\n"
|
||||
"\t --grab-scroll-up <grab> [<Shift>Up]\n"
|
||||
"\t Shortcut to scroll up\n"
|
||||
"\t --grab-scroll-down <grab> [<Shift>Down]\n"
|
||||
"\t Shortcut to scroll down\n"
|
||||
"\t --grab-page-up <grab> [<Shift>Prior]\n"
|
||||
"\t Shortcut to scroll page up\n"
|
||||
"\t --grab-page-down <grab> [<Shift>Next]\n"
|
||||
"\t Shortcut to scroll page down\n"
|
||||
"\t --grab-scroll-up <grab> [<Shift>Up]\n"
|
||||
"\t Shortcut to scroll up\n"
|
||||
"\t --grab-scroll-down <grab> [<Shift>Down]\n"
|
||||
"\t Shortcut to scroll down\n"
|
||||
"\t --grab-page-up <grab> [<Shift>Prior]\n"
|
||||
"\t Shortcut to scroll page up\n"
|
||||
"\t --grab-page-down <grab> [<Shift>Next]\n"
|
||||
"\t Shortcut to scroll page down\n"
|
||||
"\t --grab-session-next <grab> [<Ctrl><Alt>Right]\n"
|
||||
"\t Switch to next session\n"
|
||||
"\t --grab-session-prev <grab> [<Ctrl><Alt>Left]\n"
|
||||
"\t Switch to previous session\n"
|
||||
"\n"
|
||||
"Font Options:\n"
|
||||
"\t --font-engine <engine> [pango]\n"
|
||||
@ -245,6 +249,12 @@ static struct conf_grab def_grab_page_up =
|
||||
static struct conf_grab def_grab_page_down =
|
||||
CONF_SINGLE_GRAB(SHL_SHIFT_MASK, XKB_KEY_Next);
|
||||
|
||||
static struct conf_grab def_grab_session_next =
|
||||
CONF_SINGLE_GRAB(SHL_CONTROL_MASK | SHL_ALT_MASK, XKB_KEY_Right);
|
||||
|
||||
static struct conf_grab def_grab_session_prev =
|
||||
CONF_SINGLE_GRAB(SHL_CONTROL_MASK | SHL_ALT_MASK, XKB_KEY_Left);
|
||||
|
||||
struct conf_option options[] = {
|
||||
CONF_OPTION_BOOL('h', "help", aftercheck_help, &kmscon_conf.help, false),
|
||||
CONF_OPTION_BOOL('v', "verbose", NULL, &kmscon_conf.verbose, false),
|
||||
@ -265,6 +275,8 @@ struct conf_option options[] = {
|
||||
CONF_OPTION_GRAB(0, "grab-scroll-down", NULL, &kmscon_conf.grab_scroll_down, &def_grab_scroll_down),
|
||||
CONF_OPTION_GRAB(0, "grab-page-up", NULL, &kmscon_conf.grab_page_up, &def_grab_page_up),
|
||||
CONF_OPTION_GRAB(0, "grab-page-down", NULL, &kmscon_conf.grab_page_down, &def_grab_page_down),
|
||||
CONF_OPTION_GRAB(0, "grab-session-next", NULL, &kmscon_conf.grab_session_next, &def_grab_session_next),
|
||||
CONF_OPTION_GRAB(0, "grab-session-prev", NULL, &kmscon_conf.grab_session_prev, &def_grab_session_prev),
|
||||
CONF_OPTION_STRING(0, "xkb-layout", NULL, &kmscon_conf.xkb_layout, "us"),
|
||||
CONF_OPTION_STRING(0, "xkb-variant", NULL, &kmscon_conf.xkb_variant, ""),
|
||||
CONF_OPTION_STRING(0, "xkb-options", NULL, &kmscon_conf.xkb_options, ""),
|
||||
|
@ -72,6 +72,7 @@ struct kmscon_conf_t {
|
||||
char **argv;
|
||||
/* terminal scroll-back buffer size */
|
||||
unsigned int sb_size;
|
||||
|
||||
/* scroll-up grab */
|
||||
struct conf_grab *grab_scroll_up;
|
||||
/* scroll-down grab */
|
||||
@ -80,6 +81,10 @@ struct kmscon_conf_t {
|
||||
struct conf_grab *grab_page_up;
|
||||
/* page-down grab */
|
||||
struct conf_grab *grab_page_down;
|
||||
/* session-next grab */
|
||||
struct conf_grab *grab_session_next;
|
||||
/* session-prev grab */
|
||||
struct conf_grab *grab_session_prev;
|
||||
|
||||
/* seats */
|
||||
char **seats;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "conf.h"
|
||||
#include "eloop.h"
|
||||
#include "kmscon_conf.h"
|
||||
#include "kmscon_seat.h"
|
||||
@ -88,11 +89,13 @@ static void session_call(struct kmscon_session *sess, unsigned int event,
|
||||
|
||||
static void session_call_activate(struct kmscon_session *sess)
|
||||
{
|
||||
log_debug("activate session %p", sess);
|
||||
session_call(sess, KMSCON_SESSION_ACTIVATE, NULL);
|
||||
}
|
||||
|
||||
static void session_call_deactivate(struct kmscon_session *sess)
|
||||
{
|
||||
log_debug("deactivate session %p", sess);
|
||||
session_call(sess, KMSCON_SESSION_DEACTIVATE, NULL);
|
||||
}
|
||||
|
||||
@ -108,12 +111,14 @@ static void session_call_display_gone(struct kmscon_session *sess,
|
||||
session_call(sess, KMSCON_SESSION_DISPLAY_GONE, disp);
|
||||
}
|
||||
|
||||
static void session_activate(struct kmscon_session *sess)
|
||||
static int session_activate(struct kmscon_session *sess)
|
||||
{
|
||||
struct kmscon_seat *seat = sess->seat;
|
||||
|
||||
if (seat->cur_sess == sess || !sess->enabled)
|
||||
return;
|
||||
if (seat->cur_sess == sess)
|
||||
return 0;
|
||||
if (!sess->enabled)
|
||||
return -EINVAL;
|
||||
|
||||
if (seat->cur_sess) {
|
||||
if (seat->awake)
|
||||
@ -124,12 +129,15 @@ static void session_activate(struct kmscon_session *sess)
|
||||
seat->cur_sess = sess;
|
||||
if (seat->awake)
|
||||
session_call_activate(sess);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void session_deactivate(struct kmscon_session *sess)
|
||||
{
|
||||
struct kmscon_seat *seat = sess->seat;
|
||||
struct shl_dlist *iter;
|
||||
struct kmscon_session *s;
|
||||
|
||||
if (seat->cur_sess != sess)
|
||||
return;
|
||||
@ -138,18 +146,50 @@ static void session_deactivate(struct kmscon_session *sess)
|
||||
session_call_deactivate(sess);
|
||||
|
||||
seat->cur_sess = NULL;
|
||||
shl_dlist_for_each(iter, &seat->sessions) {
|
||||
sess = shl_dlist_entry(iter, struct kmscon_session, list);
|
||||
if (!sess->enabled)
|
||||
shl_dlist_for_each_but_one(iter, &sess->list, &seat->sessions) {
|
||||
s = shl_dlist_entry(iter, struct kmscon_session, list);
|
||||
if (!s->enabled)
|
||||
continue;
|
||||
|
||||
seat->cur_sess = sess;
|
||||
seat->cur_sess = s;
|
||||
if (seat->awake)
|
||||
session_call_activate(seat->cur_sess);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void seat_activate_next(struct kmscon_seat *seat)
|
||||
{
|
||||
struct shl_dlist *iter;
|
||||
struct kmscon_session *sess;
|
||||
|
||||
if (!seat->cur_sess)
|
||||
return;
|
||||
|
||||
shl_dlist_for_each_but_one(iter, &seat->cur_sess->list,
|
||||
&seat->sessions) {
|
||||
sess = shl_dlist_entry(iter, struct kmscon_session, list);
|
||||
if (!session_activate(sess))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void seat_activate_prev(struct kmscon_seat *seat)
|
||||
{
|
||||
struct shl_dlist *iter;
|
||||
struct kmscon_session *sess;
|
||||
|
||||
if (!seat->cur_sess)
|
||||
return;
|
||||
|
||||
shl_dlist_for_each_reverse_but_one(iter, &seat->cur_sess->list,
|
||||
&seat->sessions) {
|
||||
sess = shl_dlist_entry(iter, struct kmscon_session, list);
|
||||
if (!session_activate(sess))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void activate_display(struct kmscon_display *d)
|
||||
{
|
||||
int ret;
|
||||
@ -257,6 +297,29 @@ static int seat_vt_event(struct uterm_vt *vt, unsigned int event, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void seat_input_event(struct uterm_input *input,
|
||||
struct uterm_input_event *ev,
|
||||
void *data)
|
||||
{
|
||||
struct kmscon_seat *seat = data;
|
||||
|
||||
if (ev->handled)
|
||||
return;
|
||||
|
||||
if (conf_grab_matches(kmscon_conf.grab_session_next,
|
||||
ev->mods, ev->num_syms, ev->keysyms)) {
|
||||
ev->handled = true;
|
||||
seat_activate_next(seat);
|
||||
return;
|
||||
}
|
||||
if (conf_grab_matches(kmscon_conf.grab_session_prev,
|
||||
ev->mods, ev->num_syms, ev->keysyms)) {
|
||||
ev->handled = true;
|
||||
seat_activate_prev(seat);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int kmscon_seat_new(struct kmscon_seat **out,
|
||||
struct ev_eloop *eloop,
|
||||
struct uterm_vt_master *vtm,
|
||||
@ -298,24 +361,38 @@ int kmscon_seat_new(struct kmscon_seat **out,
|
||||
if (ret)
|
||||
goto err_name;
|
||||
|
||||
ret = uterm_input_register_cb(seat->input, seat_input_event, seat);
|
||||
if (ret)
|
||||
goto err_input;
|
||||
|
||||
ret = uterm_vt_allocate(seat->vtm, &seat->vt, seat->name,
|
||||
seat->input, kmscon_conf.vt, seat_vt_event,
|
||||
seat);
|
||||
if (ret)
|
||||
goto err_input;
|
||||
|
||||
ret = kmscon_terminal_register(&s, seat);
|
||||
if (ret)
|
||||
goto err_vt;
|
||||
kmscon_session_enable(s);
|
||||
goto err_input_cb;
|
||||
|
||||
ev_eloop_ref(seat->eloop);
|
||||
uterm_vt_master_ref(seat->vtm);
|
||||
*out = seat;
|
||||
|
||||
/* register built-in sessions */
|
||||
|
||||
ret = kmscon_terminal_register(&s, seat);
|
||||
if (ret == -EOPNOTSUPP)
|
||||
log_notice("terminal support not compiled in");
|
||||
else if (ret)
|
||||
goto err_sessions;
|
||||
else
|
||||
kmscon_session_enable(s);
|
||||
|
||||
return 0;
|
||||
|
||||
err_vt:
|
||||
uterm_vt_deallocate(seat->vt);
|
||||
err_sessions:
|
||||
kmscon_seat_free(seat);
|
||||
return ret;
|
||||
|
||||
err_input_cb:
|
||||
uterm_input_unregister_cb(seat->input, seat_input_event, seat);
|
||||
err_input:
|
||||
uterm_input_unref(seat->input);
|
||||
err_name:
|
||||
@ -348,6 +425,7 @@ void kmscon_seat_free(struct kmscon_seat *seat)
|
||||
}
|
||||
|
||||
uterm_vt_deallocate(seat->vt);
|
||||
uterm_input_unregister_cb(seat->input, seat_input_event, seat);
|
||||
uterm_input_unref(seat->input);
|
||||
free(seat->name);
|
||||
uterm_vt_master_unref(seat->vtm);
|
||||
@ -437,13 +515,16 @@ int kmscon_seat_register_session(struct kmscon_seat *seat,
|
||||
seat->name);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
log_debug("register session %p", sess);
|
||||
|
||||
memset(sess, 0, sizeof(*sess));
|
||||
sess->ref = 1;
|
||||
sess->seat = seat;
|
||||
sess->cb = cb;
|
||||
sess->data = data;
|
||||
|
||||
shl_dlist_link(&seat->sessions, &sess->list);
|
||||
shl_dlist_link_tail(&seat->sessions, &sess->list);
|
||||
*out = sess;
|
||||
|
||||
return 0;
|
||||
@ -471,8 +552,10 @@ void kmscon_session_unregister(struct kmscon_session *sess)
|
||||
if (!sess || !sess->seat)
|
||||
return;
|
||||
|
||||
shl_dlist_unlink(&sess->list);
|
||||
log_debug("unregister session %p", sess);
|
||||
|
||||
session_deactivate(sess);
|
||||
shl_dlist_unlink(&sess->list);
|
||||
sess->seat = NULL;
|
||||
session_call(sess, KMSCON_SESSION_UNREGISTER, NULL);
|
||||
}
|
||||
@ -508,6 +591,8 @@ void kmscon_session_enable(struct kmscon_session *sess)
|
||||
if (!sess)
|
||||
return;
|
||||
|
||||
log_debug("enable session %p", sess);
|
||||
|
||||
sess->enabled = true;
|
||||
if (sess->seat && !sess->seat->cur_sess)
|
||||
session_activate(sess);
|
||||
@ -518,6 +603,8 @@ void kmscon_session_disable(struct kmscon_session *sess)
|
||||
if (!sess)
|
||||
return;
|
||||
|
||||
log_debug("disable session %p", sess);
|
||||
|
||||
if (sess->seat)
|
||||
session_deactivate(sess);
|
||||
sess->enabled = false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user