Beispiel #1
0
/**
 * Handles the release of a mouse button. This event is only expected when
 * a placeholder is going to be released, so the only possible action is to
 * stop moving/resizing.
 */
void XEvents::handle_buttonrelease()
{
    Window expected_placeholder = m_xmodel.get_move_resize_placeholder();
    
    // If this is *not* the current placeholder, then bail
    if (expected_placeholder != m_event.xbutton.window)
        return;

    MoveResizeState state = m_xmodel.get_move_resize_state();
    Window client = m_xmodel.get_move_resize_client();

    // Figure out the attributes of the placeholder, so that way we can do
    // the movements/resizes
    XWindowAttributes attrs;
    m_xdata.get_attributes(expected_placeholder, attrs);

    switch (state)
    {
    case MR_MOVE:
        m_clients.stop_moving(client, Dimension2D(attrs.x, attrs.y));
        break;
    case MR_RESIZE:
        m_clients.stop_resizing(client, 
                                Dimension2D(attrs.width, attrs.height));
        break;
    }
}
Beispiel #2
0
Image::Image(size_t width, size_t height, SamplingDefinition scheme)
	: imageSize(width, height),
	simulatedSize(
		width + (width % scheme.stepSize.width == 0 ? 0 : scheme.stepSize.width - width % scheme.stepSize.width),
		height + (height % scheme.stepSize.height == 0 ? 0 : scheme.stepSize.height - height % scheme.stepSize.height)),
	channelSizes { Dimension2D(simulatedSize) , Dimension2D(simulatedSize) , Dimension2D(simulatedSize) },
	samplingScheme(scheme)
{
	channels = std::make_unique<ImageData>(simulatedSize);
	blocksPerChannel[0] = blocksPerChannel[1] = blocksPerChannel[2] = simulatedSize.width * simulatedSize.height / 8;
}
Beispiel #3
0
/**
 * Changes the location of a client.
 */
void ClientModel::change_location(Window client, Dimension x, Dimension y)
{
    // See whether the client should end up on a new desktop with its new
    // location
    const Box &old_desktop = m_screen[client];
    Crt *new_screen = m_crt_manager.screen_of_coord(x, y);
    const Box &new_desktop = m_crt_manager.box_of_screen(new_screen);

    m_location[client] = Dimension2D(x, y);
    m_changes.push(new ChangeLocation(client, x, y));

    if (old_desktop != new_desktop)
        to_screen_box(client, new_desktop);
}
Beispiel #4
0
/**
 * Adds a window - this is exposed specifically so that smallwm.cpp can
 * access this method when it imports existing windows.
 *
 * @param window The window to add.
 */
void XEvents::add_window(Window window)
{
    // First, test if this client is already known to us - if it is, then
    // move it onto the current desktop
    if (m_clients.is_client(window))
    {
        Desktop const *mapped_desktop = m_clients.find_desktop(window);

        // Icons must be uniconified
        if (mapped_desktop->is_icon_desktop())
            m_clients.deiconify(window);

        // Moving/resizing clients must stop being moved/resized
        if (mapped_desktop->is_moving_desktop() || mapped_desktop->is_resizing_desktop())
        {
            Window placeholder = m_xmodel.get_move_resize_placeholder();
            m_xmodel.exit_move_resize();

            XWindowAttributes placeholder_attr;
            m_xdata.get_attributes(placeholder, placeholder_attr);

            if (mapped_desktop->is_moving_desktop())
                m_clients.stop_moving(window, 
                    Dimension2D(placeholder_attr.x, placeholder_attr.y));
            else if (mapped_desktop->is_resizing_desktop())
                m_clients.stop_resizing(window, 
                    Dimension2D(placeholder_attr.width, placeholder_attr.height));
        }

        // Clients which are currently stuck on all desktops don't need to have 
        // anything done to them. Everybody else has to be moved onto the 
        // current desktop.
        if (!mapped_desktop->is_all_desktop())
            m_clients.client_reset_desktop(window);

        return;
    }

    // So, this isn't an existing client. We have to figure out now if this is
    // even a client *at all* - override_redirect indicates if this client does
    // (false) or does not (true) want to be managed
    XWindowAttributes win_attr;
    m_xdata.get_attributes(window, win_attr);

    if (win_attr.override_redirect)
        return;

    // This is a new, manageable client - register it with the client database.
    // This requires we know 3 things:
    //  - What the client wants, with regards to its initial state - either
    //    visible or iconified
    //  - The client's position (we know this one)
    //  - The client's size (we know this one too)
    //
    //  The information about the initial state is given by XWMHints
    XWMHints hints;
    bool has_hints = m_xdata.get_wm_hints(window, hints);

    InitialState init_state = IS_VISIBLE;
    if (has_hints && hints.flags & StateHint && 
                     hints.initial_state == IconicState)
        init_state = IS_HIDDEN;

    m_clients.add_client(window, init_state,
            Dimension2D(win_attr.x, win_attr.y), 
            Dimension2D(win_attr.width, win_attr.height));

    // If the client is a dialog, this will be represented in the transient 
    // hint (which is None if the client is not a dialog, or not-None if it is)
    if (m_xdata.get_transient_hint(window) != None)
        m_clients.set_layer(window, DIALOG_LAYER);

    // Finally, execute the actions tied to the window's class
    std::string win_class;
    m_xdata.get_class(window, win_class);

    if (m_config.classactions.count(win_class) > 0 && init_state != IS_HIDDEN)
    {
        ClassActions &action = m_config.classactions[win_class];

        if (action.actions & ACT_STICK)
            m_clients.toggle_stick(window);

        if (action.actions & ACT_MAXIMIZE)
            maximize_client(window);

        if (action.actions & ACT_SETLAYER)
            m_clients.set_layer(window, action.layer);

        if (action.actions & ACT_SNAP)
            snap_client(window, action.snap);

        if (action.actions & ACT_MOVE_X || action.actions & ACT_MOVE_Y)
        {
            Dimension scr_width, scr_height;
            m_xdata.get_screen_size(scr_width, scr_height);

            Dimension win_x_pos = win_attr.x;
            Dimension win_y_pos = win_attr.y;

            if (action.actions & ACT_MOVE_X)
                win_x_pos = scr_width * action.relative_x;

            if (action.actions & ACT_MOVE_Y)
                win_y_pos = scr_height * action.relative_y;

            if (win_attr.x != win_x_pos || win_attr.x != win_y_pos)
                m_clients.change_location(window, win_x_pos, win_y_pos);
        }
    }
}
Beispiel #5
0
/**
 * Updates the size of a client without causing a change.
 *
 * This is meant to inform the model of changes that happened because of the
 * client doing things on its own, and not because of us.
 */
void ClientModel::update_size(Window client, Dimension width, Dimension height)
{
    if (width > 0 && height > 0)
        m_size[client] = Dimension2D(width, height);
}