예제 #1
0
int mouse_unbind_all() {
    g_list_free_full(g_mouse_binds, mouse_binding_free);
    g_mouse_binds = NULL;
    HSClient* client = get_current_client();
    if (client) {
        grab_client_buttons(client, true);
    }
    return 0;
}
예제 #2
0
파일: clientlist.c 프로젝트: xiaq/hlwm
void window_unfocus(Window window) {
    HSDebug("window_unfocus NORMAL\n");
    window_update_border(window, g_window_border_normal_color);
    HSClient* c = get_client_from_window(window);
    if (c) {
        if (c->urgent) {
            HSDebug("window_unfocus URGENT\n");
            window_update_border(window, g_window_border_urgent_color);
        }
        grab_client_buttons(c, false);
    }
}
예제 #3
0
파일: clientlist.c 프로젝트: xiaq/hlwm
void window_focus(Window window) {
    HSClient* client = get_client_from_window(window);
    assert(client != NULL);
    // set keyboard focus
    if (!client->neverfocus) {
        XSetInputFocus(g_display, window, RevertToPointerRoot, CurrentTime);
    }
    else client_sendevent(client, g_wmatom[WMTakeFocus]);

    if (window != lastfocus) {
        /* FIXME: this is a workaround because window_focus always is called
         * twice.  see BUGS for more information
         *
         * only emit the hook if the focus *really* changes */
        // unfocus last one
        window_unfocus(lastfocus);
        hsobject_link(g_client_object, &client->object, "focus");
        ewmh_update_active_window(window);
        tag_update_each_focus_layer();
        char* title = client ? client->title->str : "?";
        char winid_str[STRING_BUF_SIZE];
        snprintf(winid_str, STRING_BUF_SIZE, "0x%x", (unsigned int)window);
        hook_emit_list("focus_changed", winid_str, title, NULL);
    }

    // change window-colors
    HSDebug("window_focus ACTIVE\n");
    window_update_border(window, g_window_border_active_color);

    lastfocus = window;
    /* do some specials for the max layout */
    bool is_max_layout = frame_focused_window(g_cur_frame) == window
                         && g_cur_frame->content.clients.layout == LAYOUT_MAX
                         && get_current_monitor()->tag->floating == false;
    if (*g_raise_on_focus || is_max_layout) {
        client_raise(client);
    }
    tag_update_focus_layer(get_current_monitor()->tag);
    grab_client_buttons(get_client_from_window(window), true);
    client_set_urgent(client, false);
}
예제 #4
0
int mouse_bind_command(int argc, char** argv, GString* output) {
    if (argc < 3) {
        return HERBST_NEED_MORE_ARGS;
    }
    unsigned int modifiers = 0;
    char* string = argv[1];
    if (!string2modifiers(string, &modifiers)) {
        g_string_append_printf(output,
            "%s: Modifier \"%s\" does not exist\n", argv[0], string);
        return HERBST_INVALID_ARGUMENT;
    }
    // last one is the mouse button
    const char* last_token = strlasttoken(string, KEY_COMBI_SEPARATORS);
    unsigned int button = string2button(last_token);
    if (button == 0) {
        g_string_append_printf(output,
            "%s: Unknown mouse button \"%s\"\n", argv[0], last_token);
        return HERBST_INVALID_ARGUMENT;
    }
    MouseFunction function = string2mousefunction(argv[2]);
    if (!function) {
        g_string_append_printf(output,
            "%s: Unknown mouse action \"%s\"\n", argv[0], argv[2]);
        return HERBST_INVALID_ARGUMENT;
    }

    // actually create a binding
    MouseBinding* mb = g_new(MouseBinding, 1);
    mb->button = button;
    mb->modifiers = modifiers;
    mb->action = function;
    mb->argc = argc - 3;
    mb->argv = argv_duplicate(argc - 3, argv + 3);;
    g_mouse_binds = g_list_prepend(g_mouse_binds, mb);
    HSClient* client = get_current_client();
    if (client) {
        grab_client_buttons(client, true);
    }
    return 0;
}
예제 #5
0
파일: clientlist.c 프로젝트: xiaq/hlwm
HSClient* manage_client(Window win) {
    if (is_herbstluft_window(g_display, win)) {
        // ignore our own window
        return NULL;
    }
    if (get_client_from_window(win)) {
        return NULL;
    }
    // init client
    HSClient* client = create_client();
    client->pid = window_pid(g_display, win);
    HSMonitor* m = get_current_monitor();
    // set to window properties
    client->window = win;
    client_update_title(client);

    unsigned int border, depth;
    Window root_win;
    int x, y;
    unsigned int w, h;
    XGetGeometry(g_display, win, &root_win, &x, &y, &w, &h, &border, &depth);
    // treat wanted coordinates as floating coords
    client->float_size.x = x;
    client->float_size.y = y;
    client->float_size.width = w;
    client->float_size.height = h;

    // apply rules
    HSClientChanges changes;
    client_changes_init(&changes, client);
    rules_apply(client, &changes);
    if (changes.tag_name) {
        client->tag = find_tag(changes.tag_name->str);
    }

    if (!changes.manage) {
        client_changes_free_members(&changes);
        client_destroy(client);
        // map it... just to be sure
        XMapWindow(g_display, win);
        return NULL;
    }

    // actually manage it
    g_hash_table_insert(g_clients, &(client->window), client);
    client->window_str = g_string_sized_new(10);
    g_string_printf(client->window_str, "0x%lx", win);
    hsobject_link(g_client_object, &client->object, client->window_str->str);
    // insert to layout
    if (!client->tag) {
        client->tag = m->tag;
    }
    // get events from window
    XSelectInput(g_display, win, CLIENT_EVENT_MASK);
    // insert window to the stack
    client->slice = slice_create_client(client);
    stack_insert_slice(client->tag->stack, client->slice);
    // insert window to the tag
    frame_insert_window(lookup_frame(client->tag->frame, changes.tree_index->str), win);
    client_update_wm_hints(client);
    if (changes.focus) {
        // give focus to window if wanted
        // TODO: make this faster!
        // WARNING: this solution needs O(C + exp(D)) time where W is the count
        // of clients on this tag and D is the depth of the binary layout tree
        frame_focus_window(client->tag->frame, win);
    }

    HSAttribute attributes[] = {
        ATTRIBUTE_STRING(   "winid",        client->window_str,     ATTR_READ_ONLY),
        ATTRIBUTE_STRING(   "title",        client->title,          ATTR_READ_ONLY),
        ATTRIBUTE_BOOL(     "fullscreen",   client->fullscreen,     client_attr_fullscreen),
        ATTRIBUTE_BOOL(     "pseudotile",   client->pseudotile,     client_attr_pseudotile),
        ATTRIBUTE_BOOL(     "ewmhrequests", client->ewmhrequests,   ATTR_ACCEPT_ALL),
        ATTRIBUTE_BOOL(     "ewmhnotify",   client->ewmhnotify,     ATTR_ACCEPT_ALL),
        ATTRIBUTE_BOOL(     "sizehints",    client->sizehints,      ATTR_ACCEPT_ALL),
        ATTRIBUTE_BOOL(     "urgent",       client->urgent,         client_attr_urgent),
        ATTRIBUTE_LAST,
    };
    hsobject_set_attributes(&client->object, attributes);

    ewmh_window_update_tag(client->window, client->tag);
    tag_set_flags_dirty();
    client_set_fullscreen(client, changes.fullscreen);
    ewmh_update_window_state(client);
    // add client after setting the correct tag for the new client
    // this ensures a panel can read the tag property correctly at this point
    ewmh_add_client(client->window);

    HSMonitor* monitor = find_monitor_with_tag(client->tag);
    if (monitor) {
        if (monitor != get_current_monitor()
            && changes.focus && changes.switchtag) {
            monitor_set_tag(get_current_monitor(), client->tag);
        }
        // TODO: monitor_apply_layout() maybe is called twice here if it
        // already is called by monitor_set_tag()
        monitor_apply_layout(monitor);
    } else {
        if (changes.focus && changes.switchtag) {
            monitor_set_tag(get_current_monitor(), client->tag);
        }
    }

    client_changes_free_members(&changes);
    grab_client_buttons(client, false);

    return client;
}