Git Product home page Git Product logo

Comments (8)

orhun avatar orhun commented on July 21, 2024

Hey,
It's good to see people discovering this project and the first issue being created :)
Actually this was on my TODO list for like a few weeks since I realized font being too small while recording GIFs for README.md. About the XSetFont() approach, you're basically right. That's one way of setting the font size. (the font, actually) So I've played around with it a little bit in get_gc function which is responsible for the main graphics context:

fn get_gc(&self, fg_color: u64) -> xlib::GC {
    let font = "-*-dejavu sans-*-*-*-*-17-*-*-*-*-*-*-*"; // font description
    let font = CString::new(font).expect("Failed to create CString");
    let xfont =
        unsafe { xlib::XLoadQueryFont(self.display.inner, font.as_ptr()) }; // load font
    unsafe {
        let gc =
            xlib::XCreateGC(self.display.inner, self.xid, 0, ptr::null_mut());
        xlib::XSetForeground(self.display.inner, gc, fg_color);
        if !xfont.is_null() {
            xlib::XSetFont(self.display.inner, gc, (*xfont).fid); // set font
        } else {
            warn!("Invalid font!"); // TODO: do this somewhere else, get_gc is called for every new window
        }
        gc
    }
}

Result:

cap

Turns out it can indeed set the font but the only problem being finding the correct font query/description. In this case, I generated the -*-dejavu sans-*-*-*-*-17-*-*-*-*-*-*-* description with using xfontsel utility:

cap

Give xfontsel utility a try. Not all of the fonts support a specific size so format!(-*-*-*-*-*-*-{}-*-*-*-*-*-*-*, font_size) might not load a font at all. (thinking aloud)

So my plan is to implement a separate font handler function/module and adding the --font flag to general settings for letting user to set a font according to the X11 font descriptions. (e.g. menyoki --font "-*-*-*-*-*-*-17-*-*-*-*-*-*-*")

Tell me what you think :)

from menyoki.

nabijaczleweli avatar nabijaczleweli commented on July 21, 2024

It's not exactly easy to find fonts that are actually big enough on my system, but this does in fact work.

It's also revealed that Window leaks an astounding amount of GCs; they're 176 bytes each, so it's not a giagnti deal memory-wise and I was gonna say that "it makes menyoki use 5% of my CPU" when idling, but applying the diff below reveals that removing overhead from the continuous allocations actually makes the program use 9% instead, as it spins in polls and redraws. This probably explains why it's so weird and flickery?

diff --git a/Cargo.lock b/Cargo.lock
index f976f92..8713a39 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -717,6 +717,7 @@ dependencies = [
  "image 0.23.12",
  "imgref",
  "kamadak-exif",
+ "lazy_static",
  "log",
  "natord",
  "png 0.16.7",
diff --git a/Cargo.toml b/Cargo.toml
index f5562c9..2ff0915 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -52,6 +52,7 @@ natord = "1.0.9"
 colored = "2.0.0"
 log = "0.4.11"
 fern_colored = { version = "0.6.1", features = ["colored"] }
+lazy_static = "1.4.0"
 
 [dependencies.clap]
 version = "2.33.3"
diff --git a/src/main.rs b/src/main.rs
index 184cc92..ac1e8e4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,6 +3,8 @@
 
 #[macro_use]
 extern crate log;
+#[macro_use]
+extern crate lazy_static;
 
 mod analyze;
 mod anim;
diff --git a/src/x11/window.rs b/src/x11/window.rs
index 1eeb01d..aec0639 100644
--- a/src/x11/window.rs
+++ b/src/x11/window.rs
@@ -5,12 +5,14 @@ use crate::window::Capture;
 use crate::x11::display::Display;
 use image::Bgra;
 use std::convert::{TryFrom, TryInto};
+use std::sync::Mutex;
 use std::ffi::CString;
 use std::fmt;
 use std::io::{self, Write};
 use std::mem::MaybeUninit;
 use std::ptr;
 use std::slice;
+use std::collections::BTreeMap;
 use textwidth::Context;
 use x11::xlib;
 
@@ -19,6 +21,12 @@ const MAX_TEXT_HEIGHT: u32 = 30;
 /* Offset for placing the text on the corner of window */
 const TEXT_CORNER_OFFSET: i32 = 20;
 
+struct GcWrapper(xlib::GC);
+unsafe impl Send for GcWrapper {}
+lazy_static! {
+	static ref GC_CACHE: Mutex<BTreeMap<u64, GcWrapper>> = Mutex::new(BTreeMap::new());
+}
+
 /* X11 window id, geometric properties and its display */
 #[derive(Clone, Copy, Debug)]
 pub struct Window {
@@ -26,6 +34,7 @@ pub struct Window {
 	display: Display,
 	pub geometry: Geometry,
 	pub area: Geometry,
+	gc: xlib::GC,
 }
 
 /* Implementations for thread-safe usage */
@@ -60,6 +69,7 @@ impl Window {
 				display,
 				geometry: Geometry::default(),
 				area: Geometry::default(),
+				gc: ptr::null_mut(),
 			}
 			.set_geometry()
 		}
@@ -132,12 +142,13 @@ impl Window {
 	 * @return GC
 	 */
 	fn get_gc(&self, fg_color: u64) -> xlib::GC {
-		unsafe {
-			let gc =
-				xlib::XCreateGC(self.display.inner, self.xid, 0, ptr::null_mut());
-			xlib::XSetForeground(self.display.inner, gc, fg_color);
-			gc
-		}
+		GC_CACHE.lock().unwrap().entry(self.xid).or_insert_with(|| {
+			unsafe {
+				let gc = xlib::XCreateGC(self.display.inner, self.xid, 0, ptr::null_mut());
+				xlib::XSetForeground(self.display.inner, gc, fg_color);
+				GcWrapper(gc)
+			}
+		}).0
 	}
 
 	/* Draw a rectangle inside the window. */

from menyoki.

orhun avatar orhun commented on July 21, 2024

It's not exactly easy to find fonts that are actually big enough on my system, but this does in fact work.

I'm thinking of adding a --font argument to record and capture for setting the font. (If that partly solves your issue.) Better than nothing I guess.
Besides, I don't know what else we can do about this.

It's also revealed that Window leaks an astounding amount of GCs; they're 176 bytes each, so it's not a giagnti deal memory-wise and I was gonna say that "it makes menyoki use 5% of my CPU" when idling, but applying the diff below reveals that removing overhead from the continuous allocations actually makes the program use 9% instead, as it spins in polls and redraws. This probably explains why it's so weird and flickery?

Flickering happens because it attemps to clear the window area when the selection (rectangle) moved or resized (also window content affects it as well I guess.) And yeah, creating GCs continuously is the reason of that CPU usage. I should re-evaluate the select_window function some time.
What's the weird part? I might be blind enough to not see that since I've been using menyoki for months.

from menyoki.

nabijaczleweli avatar nabijaczleweli commented on July 21, 2024

Yeah, being able to specify the font in the config would definitely solve this.

The weirdness got a little less weird when I killed my compositor, since my wallpaper shone through the green rectangle edges (and text, funnily enough, when moving the selection) otherwise, but combined with the screen tearing it does look quite odd as it redraws over the course of a few frames after blinking off when hovering over a link in firefox.

from menyoki.

orhun avatar orhun commented on July 21, 2024

Yeah, being able to specify the font in the config would definitely solve this.

Great!

The weirdness got a little less weird when I killed my compositor, since my wallpaper shone through the green rectangle edges (and text, funnily enough, when moving the selection) otherwise, but combined with the screen tearing it does look quite odd as it redraws over the course of a few frames after blinking off when hovering over a link in firefox.

Hmm, I'd like to look into that and solve it (if it's possible) if you can provide something visual.

from menyoki.

nabijaczleweli avatar nabijaczleweli commented on July 21, 2024

In https://youtu.be/pHBuUCFsEeA, note how the text is partially white as it moves around and as short lines shine through the borders as they come in, matching what's behind them in the root window (https://nabijaczleweli.xyz/content/maths/wiggly-circle.html#r0_sngllines2_flagpan_1600x900_60).

from menyoki.

orhun avatar orhun commented on July 21, 2024

With the latest release (v0.1.4), you can specify the font (--font) and border width (--border) while using record or capture. (also they are available in config file and as environment variables)

Test it out. You can close the issue if there's nothing else to do :)

from menyoki.

nabijaczleweli avatar nabijaczleweli commented on July 21, 2024

Yep, that works; thanks!

from menyoki.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.