//! A popup surface is a short-lived, temporary surface. it can be used to implement
//! for example menus, popovers, tooltips and other similar user interface concepts.
//! a popup can be made to take an explicit grab. see xdg_popup.grab for details.
//! when the popup is dismissed, a popup_done event will be sent out, and at the
//! same time the surface will be unmapped. see the xdg_popup.popup_done event for
//! details. explicitly destroying the xdg_popup object will also dismiss the popup
//! and unmap the surface. clients that want to dismiss the popup when another
//! surface of their own is clicked should dismiss the popup using the destroy
//! request. a newly created xdg_popup will be stacked on top of all previously
//! created xdg_popup surfaces associated with the same xdg_toplevel. the parent of
//! an xdg_popup must be mapped (see the xdg_surface description) before the
//! xdg_popup itself. the client must call wl_surface.commit on the corresponding
//! wl_surface for the xdg_popup state to take effect.

//
//
//              GENERATED BY OUR WAYLAND-SCANNER. DO NOT EDIT!
//
//

#![allow(unused)]
#![allow(clippy::from_over_into)]
#![allow(clippy::match_single_binding)]

use crate::wl::{
    Array, Connection, Handle, Interface, Message, NewId, ObjectId, Opcode, Payload, PayloadType,
    RawMessage, SendError,
};
use alloc::rc::Rc;
use alloc::string::String;
use core::cell::RefCell;
use smallvec::smallvec;

use crate::wl::protocols::common::wl_buffer::WlBuffer;
use crate::wl::protocols::common::wl_callback::WlCallback;
use crate::wl::protocols::common::wl_compositor::WlCompositor;
use crate::wl::protocols::common::wl_data_device::WlDataDevice;
use crate::wl::protocols::common::wl_data_device_manager::WlDataDeviceManager;
use crate::wl::protocols::common::wl_data_offer::WlDataOffer;
use crate::wl::protocols::common::wl_data_source::WlDataSource;
use crate::wl::protocols::common::wl_display::WlDisplay;
use crate::wl::protocols::common::wl_keyboard::WlKeyboard;
use crate::wl::protocols::common::wl_output::WlOutput;
use crate::wl::protocols::common::wl_pointer::WlPointer;
use crate::wl::protocols::common::wl_region::WlRegion;
use crate::wl::protocols::common::wl_registry::WlRegistry;
use crate::wl::protocols::common::wl_seat::WlSeat;
use crate::wl::protocols::common::wl_shell::WlShell;
use crate::wl::protocols::common::wl_shell_surface::WlShellSurface;
use crate::wl::protocols::common::wl_shm::WlShm;
use crate::wl::protocols::common::wl_shm_pool::WlShmPool;
use crate::wl::protocols::common::wl_subcompositor::WlSubcompositor;
use crate::wl::protocols::common::wl_subsurface::WlSubsurface;
use crate::wl::protocols::common::wl_surface::WlSurface;
use crate::wl::protocols::common::wl_touch::WlTouch;

use crate::wl::protocols::common::xdg_popup::*;
use crate::wl::protocols::common::xdg_positioner::XdgPositioner;
use crate::wl::protocols::common::xdg_surface::XdgSurface;
use crate::wl::protocols::common::xdg_toplevel::XdgToplevel;
use crate::wl::protocols::common::xdg_wm_base::XdgWmBase;

pub trait XdgPopupExt {
    /// This destroys the popup. explicitly destroying the xdg_popup object will also
    /// dismiss the popup, and unmap the surface. if this xdg_popup is not the "topmost"
    /// popup, a protocol error will be sent.
    fn destroy(&self) -> Result<(), SendError>;
    /// This request makes the created popup take an explicit grab. an explicit grab
    /// will be dismissed when the user dismisses the popup, or when the client destroys
    /// the xdg_popup. this can be done by the user clicking outside the surface, using
    /// the keyboard, or even locking the screen through closing the lid or a timeout.
    /// if the compositor denies the grab, the popup will be immediately dismissed. this
    /// request must be used in response to some sort of user action like a button
    /// press, key press, or touch down event. the serial number of the event should be
    /// passed as 'serial'. the parent of a grabbing popup must either be an
    /// xdg_toplevel surface or another xdg_popup with an explicit grab. if the parent
    /// is another xdg_popup it means that the popups are nested, with this popup now
    /// being the topmost popup. nested popups must be destroyed in the reverse order
    /// they were created in, e.g. the only popup you are allowed to destroy at all
    /// times is the topmost one. when compositors choose to dismiss a popup, they may
    /// dismiss every nested grabbing popup as well. when a compositor dismisses popups,
    /// it will follow the same dismissing order as required from the client. the parent
    /// of a grabbing popup must either be another xdg_popup with an active explicit
    /// grab, or an xdg_popup or xdg_toplevel, if there are no explicit grabs already
    /// taken. if the topmost grabbing popup is destroyed, the grab will be returned to
    /// the parent of the popup, if that parent previously had an explicit grab. if the
    /// parent is a grabbing popup which has already been dismissed, this popup will be
    /// immediately dismissed. if the parent is a popup that did not take an explicit
    /// grab, an error will be raised. during a popup grab, the client owning the grab
    /// will receive pointer and touch events for all their surfaces as normal (similar
    /// to an "owner-events" grab in x11 parlance), while the top most grabbing popup
    /// will always have keyboard focus.
    fn grab(&self, seat: WlSeat, serial: u32) -> Result<(), SendError>;
    /// Reposition an already-mapped popup. the popup will be placed given the details
    /// in the passed xdg_positioner object, and a xdg_popup.repositioned followed by
    /// xdg_popup.configure and xdg_surface.configure will be emitted in response. any
    /// parameters set by the previous positioner will be discarded. the passed token
    /// will be sent in the corresponding xdg_popup.repositioned event. the new popup
    /// position will not take effect until the corresponding configure event is
    /// acknowledged by the client. see xdg_popup.repositioned for details. the token
    /// itself is opaque, and has no other special meaning. if multiple reposition
    /// requests are sent, the compositor may skip all but the last one. if the popup is
    /// repositioned in response to a configure event for its parent, the client should
    /// send an xdg_positioner.set_parent_configure and possibly an
    /// xdg_positioner.set_parent_size request to allow the compositor to properly
    /// constrain the popup. if the popup is repositioned together with a parent that is
    /// being resized, but not in response to a configure event, the client should send
    /// an xdg_positioner.set_parent_size request.
    fn reposition(&self, positioner: XdgPositioner, token: u32) -> Result<(), SendError>;
}

impl XdgPopupExt for XdgPopup {
    /// This destroys the popup. explicitly destroying the xdg_popup object will also
    /// dismiss the popup, and unmap the surface. if this xdg_popup is not the "topmost"
    /// popup, a protocol error will be sent.
    fn destroy(&self) -> Result<(), SendError> {
        self.connection()
            .borrow_mut()
            .send(Request::Destroy {}.into_raw(self.id()))
    }
    /// This request makes the created popup take an explicit grab. an explicit grab
    /// will be dismissed when the user dismisses the popup, or when the client destroys
    /// the xdg_popup. this can be done by the user clicking outside the surface, using
    /// the keyboard, or even locking the screen through closing the lid or a timeout.
    /// if the compositor denies the grab, the popup will be immediately dismissed. this
    /// request must be used in response to some sort of user action like a button
    /// press, key press, or touch down event. the serial number of the event should be
    /// passed as 'serial'. the parent of a grabbing popup must either be an
    /// xdg_toplevel surface or another xdg_popup with an explicit grab. if the parent
    /// is another xdg_popup it means that the popups are nested, with this popup now
    /// being the topmost popup. nested popups must be destroyed in the reverse order
    /// they were created in, e.g. the only popup you are allowed to destroy at all
    /// times is the topmost one. when compositors choose to dismiss a popup, they may
    /// dismiss every nested grabbing popup as well. when a compositor dismisses popups,
    /// it will follow the same dismissing order as required from the client. the parent
    /// of a grabbing popup must either be another xdg_popup with an active explicit
    /// grab, or an xdg_popup or xdg_toplevel, if there are no explicit grabs already
    /// taken. if the topmost grabbing popup is destroyed, the grab will be returned to
    /// the parent of the popup, if that parent previously had an explicit grab. if the
    /// parent is a grabbing popup which has already been dismissed, this popup will be
    /// immediately dismissed. if the parent is a popup that did not take an explicit
    /// grab, an error will be raised. during a popup grab, the client owning the grab
    /// will receive pointer and touch events for all their surfaces as normal (similar
    /// to an "owner-events" grab in x11 parlance), while the top most grabbing popup
    /// will always have keyboard focus.
    fn grab(&self, seat: WlSeat, serial: u32) -> Result<(), SendError> {
        self.connection()
            .borrow_mut()
            .send(Request::Grab { seat, serial }.into_raw(self.id()))
    }
    /// Reposition an already-mapped popup. the popup will be placed given the details
    /// in the passed xdg_positioner object, and a xdg_popup.repositioned followed by
    /// xdg_popup.configure and xdg_surface.configure will be emitted in response. any
    /// parameters set by the previous positioner will be discarded. the passed token
    /// will be sent in the corresponding xdg_popup.repositioned event. the new popup
    /// position will not take effect until the corresponding configure event is
    /// acknowledged by the client. see xdg_popup.repositioned for details. the token
    /// itself is opaque, and has no other special meaning. if multiple reposition
    /// requests are sent, the compositor may skip all but the last one. if the popup is
    /// repositioned in response to a configure event for its parent, the client should
    /// send an xdg_positioner.set_parent_configure and possibly an
    /// xdg_positioner.set_parent_size request to allow the compositor to properly
    /// constrain the popup. if the popup is repositioned together with a parent that is
    /// being resized, but not in response to a configure event, the client should send
    /// an xdg_positioner.set_parent_size request.
    fn reposition(&self, positioner: XdgPositioner, token: u32) -> Result<(), SendError> {
        self.connection()
            .borrow_mut()
            .send(Request::Reposition { positioner, token }.into_raw(self.id()))
    }
}
