コード例 #1
0
/**
 * Adds a new client with some basic initial state.
 */
void ClientModel::add_client(Window client, InitialState state,
    Dimension2D location, Dimension2D size, bool autofocus)
{
    if (DIM2D_WIDTH(size) <= 0 || DIM2D_HEIGHT(size) <= 0)
        return;

    // Special care is given to honor the initial state, since it is
    // mandated by the ICCCM
    switch (state)
    {
        case IS_VISIBLE:
            m_desktops.add_member(m_current_desktop, client);
            m_changes.push(new ChangeClientDesktop(client, 0,
                        m_current_desktop));
            break;
        case IS_HIDDEN:
            m_desktops.add_member(ICON_DESKTOP, client);
            m_changes.push(new ChangeClientDesktop(client, 0, ICON_DESKTOP));
            break;
    }

    m_layers.add_member(DEF_LAYER, client);
    m_changes.push(new ChangeLayer(client, DEF_LAYER));

    // Since the size and locations are already current, don't put out
    // an event now that they're set
    m_location[client] = location;
    m_size[client] = size;
    m_cps_mode[client] = CPS_FLOATING;

    Crt *current_screen = m_crt_manager.screen_of_coord(DIM2D_X(location), DIM2D_Y(location));
    if (!current_screen)
    {
        // No monitor ever contains a negative screen
        const Box invalid_box(-1, -1, 0, 0);
        m_screen.insert(std::pair<Window, const Box>(client, invalid_box));
    }
    else
    {
        const Box &screen_box = m_crt_manager.box_of_screen(current_screen);
        m_screen.insert(std::pair<Window, const Box>(client, screen_box));
    }

    if (autofocus)
    {
        m_current_desktop->focus_cycle.add(client);

        set_autofocus(client, true);
        focus(client);
    }
    else
        set_autofocus(client, false);

    m_children[client] = new std::set<Window>();
}
コード例 #2
0
/**
 * Stops resizing a window, and fixes its position.
 */
void ClientModel::stop_resizing(Window client, Dimension2D size)
{
    Desktop* old_desktop = m_desktops.get_category_of(client);
    if (!old_desktop->is_resizing_desktop())
        return;

    if (m_was_stuck[client])
        move_to_desktop(client, ALL_DESKTOPS, false);
    else
        move_to_desktop(client, m_current_desktop, false);

    change_size(client, DIM2D_WIDTH(size), DIM2D_HEIGHT(size));

    focus(client);
}
コード例 #3
0
ファイル: x-events.cpp プロジェクト: 8l/swm
/**
 * This event is only ever called on icon windows, and causes the icon
 * window to be redrawn.
 */
void XEvents::handle_expose()
{
    Icon *the_icon = m_xmodel.find_icon_from_icon_window(
        m_event.xexpose.window);

    if (!the_icon)
        return;

    // Avoid drawing over the current contents of the icon
    the_icon->gc->clear();

    int text_x_offset;
    if (m_config.show_icons)
    {
        // Get the application's pixmap icon, and figure out where to place
        // the text (since the icon goes to the left)
        XWMHints hints;
        bool has_hints = m_xdata.get_wm_hints(the_icon->client, hints);

        if (has_hints && hints.flags & IconPixmapHint)
        {
            // Copy the pixmap into the left side of the icon, keeping
            // its size. The width of the pixmap is the same as the
            // X offset of the window name (no padding is done here).
            Dimension2D pixmap_size = the_icon->gc->copy_pixmap(
                hints.icon_pixmap, 0, 0);
            text_x_offset = DIM2D_WIDTH(pixmap_size);
        }
        else
            text_x_offset = 0;
    }
    else
        text_x_offset = 0;
        
    std::string preferred_icon_name;
    m_xdata.get_icon_name(the_icon->client, preferred_icon_name);

    // The one thing that is strange here is that the Y offset is the entire
    // icon's height. This is because Xlib draws the text, starting at the
    // Y offset, from *bottom* to *top*. I don't know why.
    the_icon->gc->draw_string(text_x_offset, m_config.icon_height,
        preferred_icon_name);
}
コード例 #4
0
/**
 * Repacks the clients at the given corner.
 */
void ClientModel::repack_corner(PackCorner corner)
{
    // We only need X because SmallWM doesn't currently support the vertical
    // packing case
    int x_incr_sign;
    int x_coord, y_coord;

    // For east/south side packings, we have to subtract the width/height of
    // the window from the current coordinate
    bool subtract_width_first, subtract_height_first;

    const Box &screen = get_root_screen();

    switch (corner)
    {
    case PACK_NORTHWEST:
        x_incr_sign = 1;
        subtract_width_first = false;
        subtract_height_first = false;
        x_coord = screen.x;
        y_coord = screen.y;
        break;
    case PACK_NORTHEAST:
        x_incr_sign = -1;
        subtract_width_first = true;
        subtract_height_first = false;
        x_coord = screen.width;
        y_coord = screen.y;
        break;
    case PACK_SOUTHWEST:
        x_incr_sign = 1;
        subtract_width_first = false;
        subtract_height_first = true;
        x_coord = 0;
        y_coord = screen.height;
        break;
    case PACK_SOUTHEAST:
        x_incr_sign = -1;
        subtract_width_first = true;
        subtract_height_first = true;
        x_coord = screen.width;
        y_coord = screen.height;
        break;
    }

    // We need to collect all the windows so that we can sort them by layout
    // order (low priority closest to the corner, higher priority farther
    // away)
    std::vector<Window> windows_on_this_corner;
    for (std::map<Window, PackCorner>::iterator iter = m_pack_corners.begin();
         iter != m_pack_corners.end();
         iter++)
    {
        if (iter->second == corner)
            windows_on_this_corner.push_back(iter->first);
    }

    MapSorter<Window, unsigned long> sorter(m_pack_priority);
    std::sort(windows_on_this_corner.begin(),
              windows_on_this_corner.end(),
              sorter);

    Dimension border = m_border_width * 2;
    for (std::vector<Window>::iterator iter = windows_on_this_corner.begin();
         iter != windows_on_this_corner.end();
         iter++)
    {
        Dimension2D &size = m_size[*iter];

        int real_x, real_y;
        if (subtract_width_first)
            real_x = x_coord - (DIM2D_WIDTH(size) + border);
        else
            real_x = x_coord;

        if (subtract_height_first)
            real_y = y_coord - (DIM2D_HEIGHT(size) + border);
        else
            real_y = y_coord;

        change_location(*iter, real_x, real_y);
        x_coord += x_incr_sign * (DIM2D_WIDTH(size) + border);
    }
}
コード例 #5
0
/**
 * Converts all the information about a client window to a textual
 * representation, which is written to the output stream.
 */
void ClientModel::dump_client_info(Window client, std::ostream &output)
{
    output << "  Window: " << std::hex << client << "\n";
    output << "    Screen: " << std::dec << m_screen[client] << "\n";
    output << "    Layer: " << std::dec <<
        static_cast<int>(m_layers.get_category_of(client)) << "\n";

    Dimension2D &location = m_location[client];
    output << "    Location: X=" << DIM2D_X(location) <<
        " Y=" << DIM2D_Y(location) << "\n";

    Dimension2D &size = m_size[client];
    output << "    Size: W=" << DIM2D_WIDTH(size) <<
        " H=" << DIM2D_HEIGHT(size) << "\n";

    ClientPosScale mode = m_cps_mode[client];
    output << "    Mode: ";
    switch (mode)
    {
    case CPS_FLOATING:
        output << "floating";
        break;
    case CPS_SPLIT_LEFT:
        output << "left-split";
        break;
    case CPS_SPLIT_RIGHT:
        output << "right-split";
        break;
    case CPS_SPLIT_TOP:
        output << "top-split";
        break;
    case CPS_SPLIT_BOTTOM:
        output << "bottom-split";
        break;
    case CPS_MAX:
        output << "maximized";
        break;
    }
    output << "\n";

    output << "    Can autofocus? " <<
        (m_autofocus[client] ? "yes" : "no") << "\n";

    output << "    Packing info: ";
    if (m_pack_corners.count(client) == 0)
    {
        output << "not packed";
    }
    else
    {
        output << "Dir=";
        switch (m_pack_corners[client])
        {
        case PACK_NORTHEAST:
            output << "NE";
            break;
        case PACK_NORTHWEST:
            output << "NW";
            break;
        case PACK_SOUTHEAST:
            output << "SE";
            break;
        case PACK_SOUTHWEST:
            output << "SW";
            break;
        }

        output << " Priority=" << m_pack_priority[client];
    }
    output << "\n";

    std::vector<Window> children;
    output << "    Children\n";
    get_children_of(client, children);
    for (std::vector<Window>::iterator childiter = children.begin();
         childiter != children.end();
         childiter++)
    {
        output << "      " << std::hex << *childiter << "\n";
    }
}