コード例 #1
0
ファイル: clientlist.c プロジェクト: kcirick/fusionwm
void client_set_floating(Client* client, bool state) {
    client->floating = state;
    Frame* frame = get_current_monitor()->tag->frame;
    frame = frame_descend(frame);
    size_t floatcount = frame->content.clients.floatcount;
    floatcount += state ? 1 : -1;
    frame->content.clients.floatcount = floatcount;
    if(state)
      client_center(client, find_monitor_with_tag(client->tag));

    monitor_apply_layout(find_monitor_with_tag(client->tag));
}
コード例 #2
0
ファイル: clientlist.c プロジェクト: kcirick/fusionwm
Client* manage_client(Window win) {
   if (get_client_from_window(win)) return NULL;

   // init client
   Client* client = create_client();
   Monitor* m = get_current_monitor();
   // set to window properties
   client->window = win;
   client_update_title(client);

   // apply rules
   int manage = 1;
   rules_apply(client, &manage);
   if (!manage) {
      destroy_client(client);
      // map it... just to be sure
      XMapWindow(gDisplay, win);
      return NULL;
   }

   unsigned int border, depth;
   Window root_win;
   int x, y;
   unsigned int w, h;
   XGetGeometry(gDisplay, win, &root_win, &x, &y, &w, &h, &border, &depth);
   // treat wanted coordinates as floating coords
   XRectangle size = client->float_size;
   size.width = w;
   size.height = h;
   size.x = m->rect.x + m->rect.width/2 - size.width/2;
   size.y = m->rect.y + m->rect.height/2 - size.height/2 + bar_height;
   client->float_size = size;
   client->last_size = size;
   XMoveResizeWindow(gDisplay, client->window, size.x, size.y, size.width, size.height);

   // actually manage it
   g_array_append_val(g_clients, client);
   XSetWindowBorderWidth(gDisplay, win, window_border_width);
   // insert to layout
   if (!client->tag)   client->tag = m->tag;

   // get events from window
   client_update_wm_hints(client);
   XSelectInput(gDisplay, win, CLIENT_EVENT_MASK);
   window_grab_button(win);
   frame_insert_window(client->tag->frame, win);
   monitor_apply_layout(find_monitor_with_tag(client->tag));

   return client;
}
コード例 #3
0
ファイル: main.c プロジェクト: xiaq/hlwm
int load_command(int argc, char** argv, GString* output) {
    // usage: load TAG LAYOUT
    HSTag* tag = NULL;
    if (argc < 2) {
        return HERBST_NEED_MORE_ARGS;
    }
    char* layout_string = argv[1];
    if (argc >= 3) {
        tag = find_tag(argv[1]);
        layout_string = argv[2];
        if (!tag) {
            g_string_append_printf(output,
                "%s: Tag \"%s\" not found\n", argv[0], argv[1]);
            return HERBST_INVALID_ARGUMENT;
        }
    } else { // use current tag
        HSMonitor* m = get_current_monitor();
        tag = m->tag;
    }
    assert(tag != NULL);
    char* rest = load_frame_tree(tag->frame, layout_string, output);
    if (output->len > 0) {
        g_string_prepend(output, "load: ");
    }
    tag_set_flags_dirty(); // we probably changed some window positions
    // arrange monitor
    HSMonitor* m = find_monitor_with_tag(tag);
    if (m) {
        frame_show_recursive(tag->frame);
        if (get_current_monitor() == m) {
            frame_focus_recursive(tag->frame);
        }
        monitor_apply_layout(m);
    } else {
        frame_hide_recursive(tag->frame);
    }
    if (!rest) {
        g_string_append_printf(output,
            "%s: Error while parsing!\n", argv[0]);
        return HERBST_INVALID_ARGUMENT;
    }
    if (rest[0] != '\0') { // if string was not parsed completely
        g_string_append_printf(output,
            "%s: Layout description was too long\n", argv[0]);
        g_string_append_printf(output,
            "%s: \"%s\" has not been parsed\n", argv[0], rest);
        return HERBST_INVALID_ARGUMENT;
    }
    return 0;
}
コード例 #4
0
ファイル: mouse.cpp プロジェクト: ILMostro/herbstluftwm
void mouse_stop_drag() {
    if (g_win_drag_client) {
        client_set_dragged(g_win_drag_client, false);
        // resend last size
        monitor_apply_layout(g_drag_monitor);
    }
    g_win_drag_client = NULL;
    g_drag_function = NULL;
    XUngrabPointer(g_display, CurrentTime);
    // remove all enternotify-events from the event queue that were
    // generated by the XUngrabPointer
    XEvent ev;
    XSync(g_display, False);
    while(XCheckMaskEvent(g_display, EnterWindowMask, &ev));
}
コード例 #5
0
ファイル: main.c プロジェクト: xiaq/hlwm
void event_on_configure(XEvent event) {
    XConfigureRequestEvent* cre = &event.xconfigurerequest;
    HSClient* client = get_client_from_window(cre->window);
    XConfigureEvent ce;
    ce.type = ConfigureNotify;
    ce.display = g_display;
    ce.event = cre->window;
    ce.window = cre->window;
    if (client) {
        bool changes = false;
        if (client->sizehints && !client->dragged) {
            cre->width += 2*cre->border_width - 2*client->last_border_width;
            cre->height += 2*cre->border_width - 2*client->last_border_width;
            if (client->float_size.width != cre->width) changes = true;
            if (client->float_size.height != cre->height) changes = true;
            client->float_size.width = cre->width;
            client->float_size.height = cre->height;
            ce.x = client->last_size.x;
            ce.y = client->last_size.y;
            ce.width = client->last_size.width;
            ce.height = client->last_size.height;
            ce.override_redirect = False;
            ce.border_width = cre->border_width;
            ce.above = cre->above;
        }
        if (changes && client->tag->floating) {
            client_resize_floating(client, find_monitor_with_tag(client->tag));
        } else if (changes && client->pseudotile) {
            monitor_apply_layout(find_monitor_with_tag(client->tag));
        } else {
        // FIXME: why send event and not XConfigureWindow or XMoveResizeWindow??
            XSendEvent(g_display, cre->window, False, StructureNotifyMask,
                       (XEvent*)&ce);
        }
    } else {
        // if client not known.. then allow configure.
        // its probably a nice conky or dzen2 bar :)
        XWindowChanges wc;
        wc.x = cre->x;
        wc.y = cre->y;
        wc.width = cre->width;
        wc.height = cre->height;
        wc.border_width = cre->border_width;
        wc.sibling = cre->above;
        wc.stack_mode = cre->detail;
        XConfigureWindow(g_display, cre->window, cre->value_mask, &wc);
    }
}
コード例 #6
0
ファイル: clientlist.c プロジェクト: kcirick/fusionwm
void client_set_fullscreen(Client* client, bool state) {
    if (client->fullscreen == state)   return;

    client->fullscreen = state;
    if (state) {
       XChangeProperty(gDisplay, client->window, g_netatom[NetWmState], XA_ATOM,
             32, PropModeReplace, (unsigned char *)&g_netatom[NetWmStateFullscreen], 1);

        XRaiseWindow(gDisplay, client->window);
    } else {
       XChangeProperty(gDisplay, client->window, g_netatom[NetWmState], XA_ATOM,
             32, PropModeReplace, (unsigned char *)0, 0);
    }

    monitor_apply_layout(find_monitor_with_tag(client->tag));
}
コード例 #7
0
ファイル: main.cpp プロジェクト: qrydat/herbstluftwm
void event_on_configure(XEvent event) {
    XConfigureRequestEvent* cre = &event.xconfigurerequest;
    HSClient* client = get_client_from_window(cre->window);
    if (client) {
        bool changes = false;
        Rectangle newRect = client->float_size;
        if (client->sizehints_floating &&
            (is_client_floated(client) || client->pseudotile))
        {
            bool width_requested = 0 != (cre->value_mask & CWWidth);
            bool height_requested = 0 != (cre->value_mask & CWHeight);
            bool x_requested = 0 != (cre->value_mask & CWX);
            bool y_requested = 0 != (cre->value_mask & CWY);
            cre->width += 2*cre->border_width;
            cre->height += 2*cre->border_width;
            if (width_requested && newRect.width  != cre->width) changes = true;
            if (height_requested && newRect.height != cre->height) changes = true;
            if (x_requested || y_requested) changes = true;
            if (x_requested) newRect.x = cre->x;
            if (y_requested) newRect.y = cre->y;
            if (width_requested) newRect.width = cre->width;
            if (height_requested) newRect.height = cre->height;
        }
        if (changes && is_client_floated(client)) {
            client->float_size = newRect;
            client_resize_floating(client, find_monitor_with_tag(client->tag));
        } else if (changes && client->pseudotile) {
            client->float_size = newRect;
            monitor_apply_layout(find_monitor_with_tag(client->tag));
        } else {
        // FIXME: why send event and not XConfigureWindow or XMoveResizeWindow??
            client_send_configure(client);
        }
    } else {
        // if client not known.. then allow configure.
        // its probably a nice conky or dzen2 bar :)
        XWindowChanges wc;
        wc.x = cre->x;
        wc.y = cre->y;
        wc.width = cre->width;
        wc.height = cre->height;
        wc.border_width = cre->border_width;
        wc.sibling = cre->above;
        wc.stack_mode = cre->detail;
        XConfigureWindow(g_display, cre->window, cre->value_mask, &wc);
    }
}
コード例 #8
0
ファイル: clientlist.c プロジェクト: kcirick/fusionwm
void unmanage_client(Window win) {
   Client* client = get_client_from_window(win);
   if (!client)   return;

   // remove from tag
   frame_remove_window(client->tag->frame, win);
   // and arrange monitor
   Monitor* m = find_monitor_with_tag(client->tag);
   if (m) monitor_apply_layout(m);
   // ignore events from it
   XSelectInput(gDisplay, win, 0);
   XUngrabButton(gDisplay, AnyButton, AnyModifier, win);
   // permanently remove it
   for(int i=0; i<g_clients->len; i++){
      if(g_array_index(g_clients, Client*, i) == client)
         g_array_remove_index(g_clients, i);
   }
}
コード例 #9
0
ファイル: clientlist.c プロジェクト: xiaq/hlwm
void client_set_fullscreen(HSClient* client, bool state) {
    client->fullscreen = state;
    if (client->ewmhnotify) {
        client->ewmhfullscreen = state;
    }
    HSStack* stack = client->tag->stack;
    if (state) {
        stack_slice_add_layer(stack, client->slice, LAYER_FULLSCREEN);
    } else {
        stack_slice_remove_layer(stack, client->slice, LAYER_FULLSCREEN);
    }
    tag_update_focus_layer(client->tag);
    monitor_apply_layout(find_monitor_with_tag(client->tag));

    char buf[STRING_BUF_SIZE];
    snprintf(buf, STRING_BUF_SIZE, "0x%lx", client->window);
    ewmh_update_window_state(client);
    hook_emit_list("fullscreen", state ? "on" : "off", buf, NULL);
}
コード例 #10
0
ファイル: main.cpp プロジェクト: qrydat/herbstluftwm
void propertynotify(XEvent* event) {
    // printf("name is: PropertyNotify\n");
    XPropertyEvent *ev = &event->xproperty;
    HSClient* client;
    if (ev->state == PropertyNewValue) {
        if (is_ipc_connectable(event->xproperty.window)) {
            ipc_handle_connection(event->xproperty.window);
        } else if((client = get_client_from_window(ev->window))) {
            if (ev->atom == XA_WM_HINTS) {
                client_update_wm_hints(client);
            } else if (ev->atom == XA_WM_NORMAL_HINTS) {
                updatesizehints(client);
                HSMonitor* m = find_monitor_with_tag(client->tag);
                if (m) monitor_apply_layout(m);
            } else if (ev->atom == XA_WM_NAME ||
                       ev->atom == g_netatom[NetWmName]) {
                client_update_title(client);
            }
        }
    }
}
コード例 #11
0
ファイル: clientlist.c プロジェクト: xiaq/hlwm
void unmanage_client(Window win) {
    HSClient* client = get_client_from_window(win);
    if (!client) {
        return;
    }
    if (client->dragged) {
        mouse_stop_drag();
    }
    // remove from tag
    frame_remove_window(client->tag->frame, win);
    // ignore events from it
    XSelectInput(g_display, win, 0);
    //XUngrabButton(g_display, AnyButton, AnyModifier, win);
    // permanently remove it
    HSTag* tag = client->tag;
    g_hash_table_remove(g_clients, &win);
    // and arrange monitor after the client has been removed from the stack
    HSMonitor* m = find_monitor_with_tag(tag);
    tag_update_focus_layer(tag);
    if (m) monitor_apply_layout(m);
    ewmh_remove_client(win);
    tag_set_flags_dirty();
}
コード例 #12
0
ファイル: clientlist.c プロジェクト: xiaq/hlwm
void client_set_pseudotile(HSClient* client, bool state) {
    client->pseudotile = state;
    monitor_apply_layout(find_monitor_with_tag(client->tag));
}
コード例 #13
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;
}