Пример #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
/**
 * Handles the motion of the pointer. The only time that this ever applies is
 * when the user has moved the placeholder window - at all other times, this
 * event is ignored.
 */
void XEvents::handle_motionnotify()
{
    // Get the placeholder's current geometry, since we need to modify the
    // placeholder relative to the way it is now
    Window placeholder = m_xmodel.get_move_resize_placeholder();
    if (placeholder == None)
        return;
    XWindowAttributes attr;
    m_xdata.get_attributes(placeholder, attr);

    // Avoid needless updates by getting the most recent version of this
    // event
    m_xdata.get_latest_event(m_event, MotionNotify);

    // Get the difference relative to the previous position
    Dimension ptr_x, ptr_y;
    m_xdata.get_pointer_location(ptr_x, ptr_y);

    Dimension2D relative_change = m_xmodel.update_pointer(ptr_x, ptr_y);

    switch (m_xmodel.get_move_resize_state())
    {
    case MR_MOVE:
        // Update the position of the placeholder
        m_xdata.move_window(placeholder, 
            attr.x + DIM2D_X(relative_change), 
            attr.y + DIM2D_Y(relative_change));
        break;
    case MR_RESIZE:
        // Update the location being careful to avoid making the placeholder
        // have a negative size
        if (attr.width + DIM2D_X(relative_change) <= 0)
            DIM2D_X(relative_change) = 0;
        if (attr.height + DIM2D_Y(relative_change) <= 0)
            DIM2D_Y(relative_change) = 0;

        m_xdata.resize_window(placeholder,
            attr.width + DIM2D_X(relative_change),
            attr.height + DIM2D_Y(relative_change));
        break;
    }
}
Пример #3
0
/**
 * Stops moving a window, and fixes its position.
 */
void ClientModel::stop_moving(Window client, Dimension2D location)
{
    Desktop* old_desktop = m_desktops.get_category_of(client);
    if (!old_desktop->is_moving_desktop())
        return;

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

    change_location(client, DIM2D_X(location), DIM2D_Y(location));

    focus(client);
}
Пример #4
0
/**
 * Updates the screen configuration, as well as the screen property of every
 * client window.
 */
void ClientModel::update_screens(std::vector<Box> &bounds)
{
    m_crt_manager.rebuild_graph(bounds);

    // Now, translate the location of every client back into its updated screen
    for (std::map<Window, Dimension2D>::iterator client_location = m_location.begin();
         client_location != m_location.end();
         client_location++)
    {
        Window client = client_location->first;
        Dimension2D &location = client_location->second;

        // Although this technically *should* occur, the way that this is handled would
        // cause the client to be moved outside of our control, and we don't want that
        if (is_packed_client(client))
            continue;

        // Keep the old screen - if the new screen is the same, we don't want
        // to send out a change notification
        const Box &old_box = m_screen[client];
        Box new_box(-1, -1, 0, 0);

        Crt *new_screen = m_crt_manager.screen_of_coord(
            DIM2D_X(location), DIM2D_Y(location));

        if (new_screen)
            new_box = m_crt_manager.box_of_screen(new_screen);

        if (new_box != old_box)
        {
            m_screen.erase(client);
            m_screen.insert(std::pair<Window, const Box>(client, new_box));

            // Why do the ref like this? Well, if it is done as a reference
            // to new_box directly, then new_box will go out of scope and
            // our data will be thoroughly shat over. Thankfully the unit
            // tests caught this one.
            m_changes.push(new ChangeScreen(client, m_screen[client]));
        }
    }

    // Since the location of the primary screen's corners may have changed, we
    // have to repack everything
    repack_corner(PACK_NORTHEAST);
    repack_corner(PACK_NORTHWEST);
    repack_corner(PACK_SOUTHEAST);
    repack_corner(PACK_SOUTHWEST);
}
Пример #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";
    }
}