Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Respect FocusIn/Out mode in a hacky way #162

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 56 additions & 41 deletions gui-agent/vmside.c
Original file line number Diff line number Diff line change
Expand Up @@ -1787,56 +1787,71 @@ static void take_focus(Ghandles * g, XID winid)

}

static void handle_focus(Ghandles * g, XID winid)
static void handle_focus_helper(Ghandles * g, XID winid, struct msg_focus msg)
{
struct msg_focus key;
struct genlist *l;
int input_hint;
int use_take_focus;

read_data(g->vchan, (char *) &key, sizeof(key));
if (key.type == FocusIn
&& (key.mode == NotifyNormal || key.mode == NotifyUngrab)) {
bool use_take_focus = false;
bool input_hint = false;
if ( (l=list_lookup(windows_list, winid)) && (l->data) )
input_hint = ((struct window_data*)l->data)->input_hint;
else {
fprintf(stderr, "WARNING handle_focus: Window 0x%x data not initialized", (int)winid);
input_hint = true;
}

if (msg.type == FocusIn) {
if (msg.mode == NotifyNormal) {
XRaiseWindow(g->display, winid);


if ( (l=list_lookup(windows_list, winid)) && (l->data) ) {
use_take_focus = ((struct window_data*)l->data)->support_take_focus;
if (((struct window_data*)l->data)->is_docked)
XRaiseWindow(g->display, ((struct window_data*)l->data)->embeder);
} else {
fprintf(stderr, "WARNING handle_focus: Window 0x%x data not initialized", (int)winid);
}

XRaiseWindow(g->display, winid);
if (input_hint) {
if (g->log_level > 1)
fprintf(stderr, "0x%x gained focus\n", (int) winid);
XSetInputFocus(g->display, winid, RevertToParent, g->time);
}

if ( (l=list_lookup(windows_list, winid)) && (l->data) ) {
input_hint = ((struct window_data*)l->data)->input_hint;
use_take_focus = ((struct window_data*)l->data)->support_take_focus;
if (((struct window_data*)l->data)->is_docked)
XRaiseWindow(g->display, ((struct window_data*)l->data)->embeder);
// Do not send WM_TAKE_FOCUS if the window doesn't support it
if (use_take_focus)
take_focus(g, winid);
}
if (msg.mode == NotifyGrab) {
XGrabPointer(g->display, winid, false, 0, GrabModeSync, GrabModeSync, None, None, CurrentTime);
} else {
fprintf(stderr, "WARNING handle_focus: Window 0x%x data not initialized", (int)winid);
input_hint = True;
use_take_focus = False;
XUngrabPointer(g->display, CurrentTime);
}

// Give input focus only to window that set the input hint
if (input_hint)
XSetInputFocus(g->display, winid, RevertToParent, g->time);

// Do not send take focus if the window doesn't support it
if (use_take_focus)
take_focus(g, winid);

if (g->log_level > 1)
fprintf(stderr, "0x%x raised\n", (int) winid);
} else if (key.type == FocusOut
&& (key.mode == NotifyNormal
|| key.mode == NotifyUngrab)) {
if ( (l=list_lookup(windows_list, winid)) && (l->data) )
input_hint = ((struct window_data*)l->data)->input_hint;
else {
fprintf(stderr, "WARNING handle_focus: Window 0x%x data not initialized", (int)winid);
input_hint = True;
} else if (msg.type == FocusOut && input_hint) {
if (msg.mode == NotifyNormal) {
int ignore;
XID winid_focused;
XGetInputFocus(g->display, &winid_focused, &ignore);
if (winid_focused == winid) {
XSetInputFocus(g->display, None, RevertToParent, g->time);
if (g->log_level > 1)
fprintf(stderr, "0x%x lost focus\n", (int) winid);
}
}
if (msg.mode == NotifyGrab) {
XGrabPointer(g->display, g->root_win, false, 0, GrabModeSync, GrabModeSync, None, None, CurrentTime);
}
if (msg.mode == NotifyUngrab) {
XUngrabPointer(g->display, CurrentTime);
}
if (input_hint)
XSetInputFocus(g->display, None, RevertToParent, g->time);

if (g->log_level > 1)
fprintf(stderr, "0x%x lost focus\n", (int) winid);
}
}

static void handle_focus(Ghandles * g, XID winid)
{
struct msg_focus msg;
read_data(g->vchan, (char *) &msg, sizeof(msg));
return handle_focus_helper(g, winid, msg);
}

static int bitset(unsigned char *keys, int num)
Expand Down