def _release_button_if_needed(scenario, timeline, container, layer_prio,
                              position, y):
    next_actions = scenario.get_actions()
    if len(next_actions) == 1:
        return
    next_action = None
    for next_action in next_actions[1:]:
        if next_action.type not in ["wait", "add-layer"]:
            break
    if not next_action:
        return

    need_release = True
    if next_action and next_action.type == "edit-container":
        edge = get_edge(next_action.structure)

        if edge == scenario.last_edge:
            need_release = False

    if next_action is None or need_release:
        scenario.dragging = False
        x = Zoomable.ns_to_pixel_accurate(position)
        event = create_event(Gdk.EventType.BUTTON_RELEASE, button=1, x=x, y=y)
        with mock.patch.object(Gtk, "get_event_widget") as get_event_widget:
            get_event_widget.return_value = container.ui
            container.ui._button_release_event_cb(None, event)

        if layer_prio > 0 and container.get_layer().get_priority(
        ) != layer_prio:
            scenario.report_simple(
                GLib.quark_from_string("scenario::execution-error"),
                "Resulting clip priority: %s"
                " is not the same as the wanted one: %s" %
                (container.get_layer().get_priority(), layer_prio))

        clean_edit_modes(timeline, scenario)
def edit_container_func(scenario, action):
    timeline = scenario.get_pipeline().props.timeline
    container = timeline.get_element(action.structure["container-name"])

    if container is None:
        for layer in timeline.get_layers():
            for clip in layer.get_clips():
                Gst.info("Existing clip: %s" % clip.get_name())

        scenario.report_simple(
            GLib.quark_from_string("scenario::execution-error"),
            "Could not find container: %s" %
            action.structure["container-name"])

        return 1

    res, position = GstValidate.action_get_clocktime(scenario, action,
                                                     "position")
    layer_prio = action.structure["new-layer-priority"]

    if res is False:
        return 0

    edge = get_edge(action.structure)
    container_ui = container.ui

    set_editing_mode(timeline, scenario, action)

    y = 21 - container_ui.translate_coordinates(timeline.ui, 0, 0)[1]

    if container.get_layer().get_priority() != layer_prio and layer_prio != -1:
        try:
            layer = timeline.get_layers()[layer_prio]
            Gst.info("Y is: %s Realized?? %s Priori: %s layer prio: %s" %
                     (layer.ui.get_allocation().y, container_ui.get_realized(),
                      container.get_layer().get_priority(), layer_prio))
            y = layer.ui.get_allocation(
            ).y - container_ui.translate_coordinates(timeline.ui, 0, 0)[1]
            if y < 0:
                y += 21
            elif y > 0:
                y -= 21
        except IndexError:
            if layer_prio == -1:
                y = -5
            else:
                layer = timeline.get_layers()[-1]
                alloc = layer.ui.get_allocation()
                y = alloc.y + alloc.height + 10 - container_ui.translate_coordinates(
                    timeline.ui, 0, 0)[1]

    if not hasattr(scenario, "last_edge"):
        scenario.last_edge = edge

    if not hasattr(scenario, "dragging") or scenario.dragging is False \
            or scenario.last_edge != edge:
        event_widget = container.ui
        if isinstance(container, GES.SourceClip):
            if edge == GES.Edge.EDGE_START:
                event_widget = container.ui.left_handle
            elif edge == GES.Edge.EDGE_END:
                event_widget = container.ui.right_handle

        scenario.dragging = True
        event = create_event(Gdk.EventType.BUTTON_PRESS, button=1, y=y)
        with mock.patch.object(Gtk, "get_event_widget") as get_event_widget:
            get_event_widget.return_value = event_widget
            timeline.ui._button_press_event_cb(event_widget, event)

    x = Zoomable.ns_to_pixel_accurate(
        position) - container_ui.translate_coordinates(
            timeline.ui.layout.layers_vbox, 0, 0)[0]
    event = create_event(Gdk.EventType.MOTION_NOTIFY,
                         button=1,
                         x=x,
                         y=y,
                         state=Gdk.ModifierType.BUTTON1_MASK)
    with mock.patch.object(Gtk, "get_event_widget") as get_event_widget:
        get_event_widget.return_value = container.ui
        timeline.ui._motion_notify_event_cb(None, event)

    GstValidate.print_action(
        action, "Editing %s to %s in %s mode, edge: %s "
        "with new layer prio: %d\n" %
        (action.structure["container-name"], Gst.TIME_ARGS(position),
         scenario.last_mode, edge, layer_prio))

    _release_button_if_needed(scenario, timeline, container, layer_prio,
                              position, y)
    scenario.last_edge = edge

    return 1