-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #85 from mahkoh/jorth/activation
wayland: implement xdg-activation
- Loading branch information
Showing
28 changed files
with
676 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
use { | ||
crate::{ | ||
client::{Client, ClientError}, | ||
leaks::Tracker, | ||
object::Object, | ||
utils::{ | ||
activation_token::{activation_token, ActivationToken}, | ||
buffd::{MsgParser, MsgParserError}, | ||
}, | ||
wire::{xdg_activation_token_v1::*, XdgActivationTokenV1Id}, | ||
}, | ||
std::{cell::Cell, rc::Rc}, | ||
thiserror::Error, | ||
}; | ||
|
||
const MAX_TOKENS_PER_CLIENT: usize = 8; | ||
|
||
pub struct XdgActivationTokenV1 { | ||
pub id: XdgActivationTokenV1Id, | ||
pub client: Rc<Client>, | ||
pub tracker: Tracker<Self>, | ||
already_used: Cell<bool>, | ||
} | ||
|
||
impl XdgActivationTokenV1 { | ||
pub fn new(id: XdgActivationTokenV1Id, client: &Rc<Client>) -> Self { | ||
Self { | ||
id, | ||
client: client.clone(), | ||
tracker: Default::default(), | ||
already_used: Cell::new(false), | ||
} | ||
} | ||
|
||
fn set_serial(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationTokenV1Error> { | ||
let _req: SetSerial = self.client.parse(self, parser)?; | ||
Ok(()) | ||
} | ||
|
||
fn set_app_id(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationTokenV1Error> { | ||
let _req: SetAppId = self.client.parse(self, parser)?; | ||
Ok(()) | ||
} | ||
|
||
fn set_surface(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationTokenV1Error> { | ||
let req: SetSurface = self.client.parse(self, parser)?; | ||
self.client.lookup(req.surface)?; | ||
Ok(()) | ||
} | ||
|
||
fn commit(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationTokenV1Error> { | ||
let _req: Commit = self.client.parse(self, parser)?; | ||
if self.already_used.replace(true) { | ||
return Err(XdgActivationTokenV1Error::AlreadyUsed); | ||
} | ||
let token = activation_token(); | ||
self.client.state.activation_tokens.set(token, ()); | ||
let mut tokens = self.client.activation_tokens.borrow_mut(); | ||
if tokens.len() >= MAX_TOKENS_PER_CLIENT { | ||
if let Some(oldest) = tokens.pop_front() { | ||
self.client.state.activation_tokens.remove(&oldest); | ||
} | ||
} | ||
tokens.push_back(token); | ||
self.send_done(token); | ||
Ok(()) | ||
} | ||
|
||
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationTokenV1Error> { | ||
let _req: Destroy = self.client.parse(self, parser)?; | ||
self.client.remove_obj(self)?; | ||
Ok(()) | ||
} | ||
|
||
fn send_done(&self, token: ActivationToken) { | ||
let token = token.to_string(); | ||
self.client.event(Done { | ||
self_id: self.id, | ||
token: &token, | ||
}); | ||
} | ||
} | ||
|
||
object_base! { | ||
self = XdgActivationTokenV1; | ||
|
||
SET_SERIAL => set_serial, | ||
SET_APP_ID => set_app_id, | ||
SET_SURFACE => set_surface, | ||
COMMIT => commit, | ||
DESTROY => destroy, | ||
} | ||
|
||
impl Object for XdgActivationTokenV1 {} | ||
|
||
simple_add_obj!(XdgActivationTokenV1); | ||
|
||
#[derive(Debug, Error)] | ||
pub enum XdgActivationTokenV1Error { | ||
#[error(transparent)] | ||
ClientError(Box<ClientError>), | ||
#[error("Parsing failed")] | ||
MsgParserError(#[source] Box<MsgParserError>), | ||
#[error("The activation token has already been used")] | ||
AlreadyUsed, | ||
} | ||
efrom!(XdgActivationTokenV1Error, ClientError); | ||
efrom!(XdgActivationTokenV1Error, MsgParserError); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
use { | ||
crate::{ | ||
client::{Client, ClientError}, | ||
globals::{Global, GlobalName}, | ||
ifs::xdg_activation_token_v1::XdgActivationTokenV1, | ||
leaks::Tracker, | ||
object::Object, | ||
utils::{ | ||
activation_token::ActivationToken, | ||
buffd::{MsgParser, MsgParserError}, | ||
opaque::OpaqueError, | ||
}, | ||
wire::{xdg_activation_v1::*, XdgActivationV1Id}, | ||
}, | ||
std::rc::Rc, | ||
thiserror::Error, | ||
}; | ||
|
||
pub struct XdgActivationV1Global { | ||
pub name: GlobalName, | ||
} | ||
|
||
impl XdgActivationV1Global { | ||
pub fn new(name: GlobalName) -> Self { | ||
Self { name } | ||
} | ||
|
||
fn bind_( | ||
self: Rc<Self>, | ||
id: XdgActivationV1Id, | ||
client: &Rc<Client>, | ||
version: u32, | ||
) -> Result<(), XdgActivationV1Error> { | ||
let mgr = Rc::new(XdgActivationV1 { | ||
id, | ||
client: client.clone(), | ||
tracker: Default::default(), | ||
version, | ||
}); | ||
track!(client, mgr); | ||
client.add_client_obj(&mgr)?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
global_base!(XdgActivationV1Global, XdgActivationV1, XdgActivationV1Error); | ||
|
||
simple_add_global!(XdgActivationV1Global); | ||
|
||
impl Global for XdgActivationV1Global { | ||
fn singleton(&self) -> bool { | ||
true | ||
} | ||
|
||
fn version(&self) -> u32 { | ||
1 | ||
} | ||
} | ||
|
||
pub struct XdgActivationV1 { | ||
pub id: XdgActivationV1Id, | ||
pub client: Rc<Client>, | ||
pub tracker: Tracker<Self>, | ||
pub version: u32, | ||
} | ||
|
||
impl XdgActivationV1 { | ||
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationV1Error> { | ||
let _req: Destroy = self.client.parse(self, parser)?; | ||
self.client.remove_obj(self)?; | ||
Ok(()) | ||
} | ||
|
||
fn get_activation_token(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationV1Error> { | ||
let req: GetActivationToken = self.client.parse(self, parser)?; | ||
let token = Rc::new(XdgActivationTokenV1::new(req.id, &self.client)); | ||
track!(self.client, token); | ||
self.client.add_client_obj(&token)?; | ||
Ok(()) | ||
} | ||
|
||
fn activate(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationV1Error> { | ||
let req: Activate = self.client.parse(self, parser)?; | ||
let token: ActivationToken = req.token.parse()?; | ||
let surface = self.client.lookup(req.surface)?; | ||
if self.client.state.activation_tokens.remove(&token).is_none() { | ||
log::warn!( | ||
"Client requested activation with unknown token {}", | ||
req.token | ||
); | ||
return Ok(()); | ||
} | ||
surface.request_activation(); | ||
Ok(()) | ||
} | ||
} | ||
|
||
object_base! { | ||
self = XdgActivationV1; | ||
|
||
DESTROY => destroy, | ||
GET_ACTIVATION_TOKEN => get_activation_token, | ||
ACTIVATE => activate, | ||
} | ||
|
||
impl Object for XdgActivationV1 {} | ||
|
||
simple_add_obj!(XdgActivationV1); | ||
|
||
#[derive(Debug, Error)] | ||
pub enum XdgActivationV1Error { | ||
#[error(transparent)] | ||
ClientError(Box<ClientError>), | ||
#[error("Parsing failed")] | ||
MsgParserError(#[source] Box<MsgParserError>), | ||
#[error("Could not parse the activation token")] | ||
ParseActivationToken(#[from] OpaqueError), | ||
} | ||
efrom!(XdgActivationV1Error, ClientError); | ||
efrom!(XdgActivationV1Error, MsgParserError); |
Oops, something went wrong.