focusing, almost

This commit is contained in:
missing 2022-06-28 21:55:46 -05:00
parent 1d988b7e38
commit f7855e4a52
2 changed files with 86 additions and 22 deletions

View file

@ -173,7 +173,7 @@ async fn process_event<Dpy: AsyncDisplay + ?Sized>(
}
// forward the request
// by the time we get here someone may have already deleted their window (xterm, im looking at you!)
// by the time we get here someone may have already deleted their window
may_not_exist(ev.window.configure_async(conn, params).await)?;
}
Event::UnmapNotify(ev) => {
@ -181,6 +181,12 @@ async fn process_event<Dpy: AsyncDisplay + ?Sized>(
manager.remove_client(conn, ev.window).await?;
}
}
Event::ButtonPress(ev) => {
dbg!(&ev);
if ev.detail == 1 {
manager.set_focus(conn, ev.event).await?;
}
}
_ => {}
}
Ok(())

View file

@ -13,10 +13,11 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
use breadx::auto::xproto::{InputFocus, SetInputFocusRequest};
use breadx::prelude::{AsyncDisplayXprotoExt, SetMode};
use breadx::{
AsyncDisplay, BreadError, ConfigureWindowParameters, ErrorCode, EventMask, Window,
WindowParameters,
AsyncDisplay, AsyncDisplayExt, BreadError, ConfigureWindowParameters, ErrorCode, EventMask,
Window, WindowParameters, XidType,
};
use slotmap::{new_key_type, SlotMap};
use std::collections::HashMap;
@ -207,6 +208,51 @@ impl XcrabWindowManager {
Some(new_pane_key)
}
async fn focus_update_map<Dpy: AsyncDisplay + ?Sized>(
&mut self,
conn: &mut Dpy,
frame: FramedWindow,
parent_key: XcrabKey,
) -> Result<()> {
let win = frame.win;
// we cant `set_focus` here since `win` isnt yet mapped
self.focused = Some(win);
self.update_rectangle(conn, parent_key, None).await?;
frame.map(conn).await?;
self.update_focused(conn).await?;
Ok(())
}
/// Tells x about the currently focused window.
pub async fn update_focused<Dpy: AsyncDisplay + ?Sized>(
&mut self,
conn: &mut Dpy,
) -> Result<()> {
// unfortunately, i cannot find a method on `conn` to set the focus.
// https://www.x.org/releases/current/doc/xproto/x11protocol.html#Encoding::Requests
let mut req = SetInputFocusRequest {
req_type: 42, // constant, specified in x protocol docs.
revert_to: InputFocus::None,
length: 3, // constant, specified in x protocol docs.
focus: Window::from_xid(0), // None
time: 0, // CurrentTime
};
if let Some(focus) = self.focused {
req.focus = focus;
}
conn.exchange_request_async(req).await?;
Ok(())
}
/// Adds a new client.
pub async fn add_client<Dpy: AsyncDisplay + ?Sized>(
&mut self,
@ -317,12 +363,7 @@ impl XcrabWindowManager {
self.clients.insert(win, new_rect_key);
self.focused = Some(win);
// update the parent rectangle to also update all the siblings of our new rect
self.update_rectangle(conn, parent_key, None).await?;
frame.map(conn).await?;
self.focus_update_map(conn, frame, parent_key).await?;
Ok(())
}
@ -399,12 +440,7 @@ impl XcrabWindowManager {
self.clients.insert(win, new_rect_key);
self.focused = Some(win);
// update
self.update_rectangle(conn, parent_key, None).await?;
frame.map(conn).await?;
self.focus_update_map(conn, frame, parent_key).await?;
Ok(())
}
@ -432,11 +468,7 @@ impl XcrabWindowManager {
self.clients.insert(win, key);
self.focused = Some(win);
self.update_rectangle(conn, key, None).await?;
frame.map(conn).await?;
self.focus_update_map(conn, frame, key).await?;
Ok(())
}
@ -461,7 +493,8 @@ impl XcrabWindowManager {
match &mut rect.contents {
RectangleContents::Pane(pane) => {
if !pane.children.is_empty() {
let new_dimensions = dimensions.split(pane.directionality, pane.children.len());
let new_dimensions =
dimensions.split(pane.directionality, pane.children.len());
for (key, dimensions) in pane
.children
@ -525,7 +558,9 @@ impl XcrabWindowManager {
self.rects.remove(client_key);
if self.focused.unwrap() == win {
self.focused = self.clients.keys().next().copied();
self.focused = self.clients.keys().copied().next();
self.update_focused(conn).await?;
}
self.update_rectangle(conn, parent_key, None).await?;
@ -545,6 +580,26 @@ impl XcrabWindowManager {
Ok(())
}
}
pub async fn set_focus<Dpy: AsyncDisplay + ?Sized>(
&mut self,
conn: &mut Dpy,
win: Window,
) -> Result<()> {
let client_key = *self
.clients
.get(&win)
.ok_or(XcrabError::ClientDoesntExist)?;
self.focused = Some(win);
self.update_focused(conn).await?;
self.update_rectangle(conn, self.rects.get(client_key).unwrap().parent, None)
.await?;
Ok(())
}
}
pub fn may_not_exist(res: breadx::Result) -> breadx::Result {
@ -674,6 +729,9 @@ async fn frame<Dpy: AsyncDisplay + ?Sized>(conn: &mut Dpy, win: Window) -> Resul
)
.await?;
win.set_event_mask_async(conn, EventMask::BUTTON_PRESS)
.await?;
may_not_exist(win.change_save_set_async(conn, SetMode::Insert).await)?;
may_not_exist(win.reparent_async(conn, frame, 0, 0).await)?;