x and y parameters of x11 library don't have any effect on window - rust

I'm using the x11cb library, used to interact with the x11 server using Rust.
use std::error::Error;
use x11rb::connection::Connection;
use x11rb::protocol::xproto::*;
use x11rb::COPY_DEPTH_FROM_PARENT;
fn main() -> Result<(), Box<dyn Error>> {
// Open the connection to the X server. Use the DISPLAY environment variable.
let (conn, screen_num) = x11rb::connect(None)?;
// Get the screen #screen_num
let screen = &conn.setup().roots[screen_num];
// Ask for our window's Id
let win = conn.generate_id()?;
// Create the window
conn.create_window(
COPY_DEPTH_FROM_PARENT, // depth (same as root)
win, // window Id
screen.root, // parent window
200, // x
200, // y
150, // width
150, // height
10, // border width
WindowClass::INPUT_OUTPUT, // class
screen.root_visual, // visual
&Default::default(),
)?; // masks, not used yet
// Map the window on the screen
conn.map_window(win)?;
// Make sure commands are sent before the sleep, so window is shown
conn.flush()?;
std::thread::sleep(std::time::Duration::from_secs(10));
Ok(())
}
The window resizes if I change the width and height parameters. However, the window doesn't change positions if I modify the x and y parameters.
What could be the reason?
Rust Playground
Note: I'm using Ubuntu 22.10 with X11 and NVIDIA propetary drivers.
Update:
For some reason, this successfully repositions the window (but don't know why modifying x and y in create_window doesn't):
let values = ConfigureWindowAux::default().x(500).y(200);
conn.configure_window(win, &values)?;

Related

How do I keep window's size constant while resizing host window on imgui with Rust?

I want contents' size in a imgui window looks always same, but on resizing OS window, imgui window size and its contents scale too. Actually contents looks 'wrong' when resized, this is scaled down figure of 'hello world' example from imgui-rs repository.
I think I should achieve it by using glViewport, but it looks like I have no access to the function or equivalent things, and ContextWrapper::resize has no effect.
Event::NewEvents(_) => {
let now = Instant::now();
imgui.io_mut().update_delta_time(now - last_frame);
last_frame = now;
}
Event::MainEventsCleared => {
let gl_window = display.gl_window();
platform
.prepare_frame(imgui.io_mut(), gl_window.window())
.expect("Failed to prepare frame");
gl_window.window().request_redraw();
}
Event::RedrawRequested(_) => {
let ui = imgui.new_frame();
let mut run = true;
run_ui(&mut run, ui);
if !run {
*control_flow = ControlFlow::Exit;
}
let gl_window = display.gl_window();
let mut target = display.draw();
target.clear_color_srgb(1.0, 1.0, 1.0, 1.0);
platform.prepare_render(ui, gl_window.window());
let draw_data = imgui.render();
renderer
.render(&mut target, draw_data)
.expect("Rendering failed");
target.finish().expect("Failed to swap buffers");
}
Event::WindowEvent {
event: WindowEvent::Resized(size),
..
} => {
display.gl_window().resize(size);
}
What should I do to keep contents' size constant and to render things correctly?
I'm using imgui with glium and winit.

what's the easy way to make a simple window and catch key presses in Rust?

I am a blind Rust learner and i'm trying to make a simple audiogame engine for blind people but in rust.
Now I'm trying to make a simple window. A game for blind uses only audio and keyboard, so i have a question.
I'm trying to create an empty window and catch key presses to be able to make a self voiced user interface and game interaction using keyboard only, without mouce. what's the best solution for that?
I tryed to use winit and winit input helper, but maybe there is a better way to do that?
use winit::event::VirtualKeyCode;
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::WindowBuilder;
use winit_input_helper::WinitInputHelper;
pub fn show_window() {
let mut input = WinitInputHelper::new();
let event_loop = EventLoop::new();
let _window = WindowBuilder::new().build(&event_loop).unwrap();
event_loop.run(move |event, _, control_flow| {
// Pass every event to the WindowInputHelper.
// It will return true when the last event has been processed and it is time to run your application logic.
if input.update(&event) {
// query keypresses this update
if input.key_pressed_os(VirtualKeyCode::A) {
println!("The 'A' key was pressed on the keyboard (OS repeating)");
}
if input.key_pressed(VirtualKeyCode::A) {
println!("The 'A' key was pressed on the keyboard");
}
if input.key_released(VirtualKeyCode::Q) || input.quit() {
*control_flow = ControlFlow::Exit;
return;
}
}
});
}

How to let Gtk CellRendererText display newlines during edit?

My Gtk app currently reads data from an external database/file, then add it to a Gtk Treeview. One of the columns allows newlines, which is correctly displayed in the Treeview when single-paragraph-mode is false.
However, when I double click to edit, the cell turns into a single line entry box where a carriage return symbol (like ⤶) replaces the newlines.
This makes it impossible to edit a cell with lots of newlines because they appear as one single line. Is it possible to render the newlines as actual newlines during editing? In other words, I want single-paragraph-mode=false to apply to the cell when it is being edited
I've read the documentation for CellRendererText and CellRenderer, but it is rather lacking. Things like max-width-chars apply to the cell whether editing or not.
This code demonstrates what I mean. (It uses gtk-rs but an answer using C is fine too):
use gtk::glib;
use gtk::prelude::*;
fn main() {
let application = gtk::Application::new(
Some("com.example.xyz"),
Default::default(),
);
application.connect_activate(build_ui);
application.run();
}
fn build_ui(application: &gtk::Application) {
let window = gtk::ApplicationWindow::new(application);
window.set_title(Some("App"));
window.set_default_size(800, 800);
let grid = gtk::Grid::builder()
.column_spacing(5)
.row_spacing(10)
.build();
window.set_child(Some(&grid));
let (treeview, _treestore) = build_treeview();
let sw = gtk::ScrolledWindow::builder()
.child(&treeview)
.vexpand(false)
.vexpand_set(false)
.max_content_height(10)
.build();
// column, row, width, height
grid.attach(&sw, 0, 0, 1, 1);
window.show();
}
fn build_treeview() -> (gtk::TreeView, gtk::TreeStore) {
let treestore = gtk::TreeStore::new(&[glib::Type::STRING].repeat(4));
let treeview = gtk::TreeView::builder()
.hexpand(true)
.vexpand(true)
.enable_grid_lines(gtk::TreeViewGridLines::Both)
.model(&treestore)
.build();
for (i, title) in ["Title", "Description", "Path1", "Path2"]
.iter()
.enumerate()
{
let cell_renderer = gtk::CellRendererText::builder()
.editable(true)
.xalign(0.0)
.single_paragraph_mode(false)
.build();
treeview.insert_column_with_attributes(
i.try_into().unwrap(),
title,
&cell_renderer,
&[(&"text", i.try_into().unwrap())],
);
let ts = treestore.clone();
cell_renderer.connect_edited(move |_renderer, row, text| {
ts.set_value(
&ts.iter(&row).unwrap(),
i.try_into().unwrap(),
&text.to_value()
);
});
}
treestore.insert_with_values(
None,
None,
&[
(0, &"one"),
(1, &"two\ntwo\ntwo\ntwo"),
(2, &"three"),
(3, &"four"),
],
);
(treeview, treestore)
}

Positioning the borderless window in neutralino.js

Is there any way we can position the borderless window in the file neutralino.config.json?
like : "borderless": { ...args }
or any other ways?
Now it just starts at somewhere random and cannot be moved
You can call Neutralino.window.move(x,y) in your javascript. (0,0) is the (leftmost,top) of the screen. You can find other window functions at https://neutralino.js.org/docs/api/window.
As an extension of your question, and like Klauss A's instinct suggests, you can call Neutralino.window.setDraggableRegion('id-of-element') where id-of-element is, as the name suggests, an id of an element in your html. Then, when you click and drag that element, Neutralino will automatically call Neutralino.window.move(x,y). setDraggableRegion() is not in the docs, but you can see it in the tutorial they made on YouTube, and it is still in the code.
The thing is, how Neutralino does this is by posting a message to the server, which adds quite a bit of delay, causing the drag to stutter. Here is the relevant code snippet in a prettified version of the neutralino.js file:
...
t.move = function(e, t) {
return r.request({
url: "window.move",
type: r.RequestType.POST,
isNativeMethod: !0,
data: {
x: e,
y: t
}
})
}, t.setDraggableRegion = function(e) {
return new Promise(((t, i) => {
let r = document.getElementById(e),
o = 0,
u = 0;
function s(e) {
return n(this, void 0, void 0, (function*() {
yield Neutralino.window.move(e.screenX - o, e.screenY - u)
}))
}
r || i(`Unable to find dom element: #${e}`), r.addEventListener("mousedown", (e => {
o = e.clientX, u = e.clientY, r.addEventListener("mousemove", s)
})), r.addEventListener("mouseup", (() => {
r.removeEventListener("mousemove", s)
})), t()
}))
}
...
I suspected this formulation of adding to the lag, since function* is a generator, and thus is inherently untrustworthy (citation needed). I re-wrote it in plain javascript, and reduced some of the lag. It still stutters, just not as much.
var dragging = false, posX, posY;
var draggableElement = document.getElementById('id-of-element');
draggableElement.onmousedown = function (e) {
posX = e.pageX, posY = e.pageY;
dragging = true;
}
draggableElement.onmouseup = function (e) {
dragging = false;
}
document.onmousemove = function (e) {
if (dragging) Neutralino.window.move(e.screenX - posX, e.screenY - posY);
}
I hope this helps. I was digging around in all this because the caption bar (aka, title bar) of the window is different from my system's color theme. I thought, "maybe I'll create my own title bar in HTML, with CSS styling to match my app." But due to the stuttering issues, I find it is better to have a natively-draggable title bar that doesn't match anything. I'm still digging around in the Neutralino C++ code to see if I could modify it and add a non-client rendering message handler (on Windows), to color the title bar the same as my app and still have nice smooth dragging. That way it would look "borderless" but still be movable.
I am having the same problem. My naive instinct is telling me that probably could be a way to create a custom element bar and use a function upon click& drag to move the window around.
Moving Windows in Neutralino is Quite Simple.
You can use the Neutralino.window API to move the windows.
Example:
Neutralino.window.move(x, y);
here x and y are the Coordinates on which our window will move to.
Note the this moves the window from the Top Left Corner of the window.
I have made this Neutralino Template - NeutralinoJS App With Custom Titlebar which might be useful if you are making a custom titlebar for your application.

Can't set button color

Based on this UI example I've add a custom button at the end of on_start method. But when I run the game the button body is invisible, only its text is shown ("1234567").
The code I added to the example:
// ...
use amethyst::assets::AssetStorage;
use amethyst::assets::Handle;
use amethyst::assets::Loader;
use amethyst::renderer::loaders::load_from_srgba;
use amethyst::renderer::palette::Srgba;
use amethyst::renderer::Texture;
use amethyst::renderer::types::TextureData;
use amethyst::ui::Anchor;
use amethyst::ui::UiButtonBuilder;
use amethyst::ui::UiImage;
// ...
impl SimpleState for Example {
fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) {
// ...
let texture_handle: Handle<Texture> = {
let loader = world.read_resource::<Loader>();
let texture_assets = world.read_resource::<AssetStorage<Texture>>();
let texture_builder = load_from_srgba(Srgba::new(0.8, 0.6, 0.3, 1.0));
loader.load_from_data(TextureData::from(texture_builder), (), &texture_assets)
};
let button = UiButtonBuilder::<(), u32>::new("1234567".to_string())
.with_id(666)
.with_font_size(12.0)
.with_position(64.0, -64.0)
.with_size(64.0 * 3.0, 64.0)
.with_anchor(Anchor::TopMiddle)
// HAS NO EFFECT
.with_image(texture_handle)
// HAS NO EFFECT
.with_hover_image(UiImage::SolidColor([0.1, 0.1, 0.1, 0.5]))
.with_layer(12.0)
.build_from_world(&world);
world.insert(button);
}
}
// ...
What is the proper way to create a button on the fly with custom color?
I'm using amethyst v0.15.
There is a bug with the UiButtonBuilder. I just created this issue: https://github.com/amethyst/amethyst/issues/2298

Resources