first commit
This commit is contained in:
commit
9ea6375874
5 changed files with 238 additions and 0 deletions
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Ilia Bozhinov
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
2
README.md
Normal file
2
README.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# wayfire-plugins
|
||||||
|
A repository for Wayfire plugins which I use to tweak my own desktop
|
34
meson.build
Normal file
34
meson.build
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
project(
|
||||||
|
'wf-roundedcorners',
|
||||||
|
'c',
|
||||||
|
'cpp',
|
||||||
|
version: '0.1',
|
||||||
|
license: 'MIT',
|
||||||
|
meson_version: '>=0.51.0',
|
||||||
|
default_options: [
|
||||||
|
'cpp_std=c++17',
|
||||||
|
'c_std=c11',
|
||||||
|
'warning_level=2',
|
||||||
|
'werror=false',
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
wayfire = dependency('wayfire')
|
||||||
|
wlroots = dependency('wlroots')
|
||||||
|
wfconfig = dependency('wf-config')
|
||||||
|
|
||||||
|
add_project_arguments(['-DWLR_USE_UNSTABLE'], language: ['cpp', 'c'])
|
||||||
|
add_project_arguments(['-DWAYFIRE_PLUGIN'], language: ['cpp', 'c'])
|
||||||
|
add_project_link_arguments(['-rdynamic'], language:'cpp')
|
||||||
|
|
||||||
|
subdir('src')
|
||||||
|
subdir('metadata')
|
||||||
|
|
||||||
|
summary = [
|
||||||
|
'',
|
||||||
|
'----------------',
|
||||||
|
'wf-roundcorner @0@'.format(meson.project_version()),
|
||||||
|
'----------------',
|
||||||
|
''
|
||||||
|
]
|
||||||
|
message('\n'.join(summary))
|
3
src/meson.build
Normal file
3
src/meson.build
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
rc = shared_module('rounded-corners', 'rounded-corners.cpp',
|
||||||
|
dependencies: [wayfire, wlroots],
|
||||||
|
install: true, install_dir: wayfire.get_variable(pkgconfig: 'plugindir'))
|
178
src/rounded-corners.cpp
Normal file
178
src/rounded-corners.cpp
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
#include <wayfire/view-transform.hpp>
|
||||||
|
#include <wayfire/opengl.hpp>
|
||||||
|
#include <wayfire/plugin.hpp>
|
||||||
|
#include <wayfire/signal-definitions.hpp>
|
||||||
|
#include <wayfire/util/log.hpp>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const std::string vertex_source = R"(
|
||||||
|
#version 100
|
||||||
|
attribute mediump vec2 position;
|
||||||
|
varying mediump vec2 fposition;
|
||||||
|
|
||||||
|
uniform mat4 matrix;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = matrix * vec4(position, 0.0, 1.0);
|
||||||
|
fposition = position;
|
||||||
|
})";
|
||||||
|
|
||||||
|
const std::string frag_source = R"(
|
||||||
|
#version 100
|
||||||
|
@builtin_ext@
|
||||||
|
|
||||||
|
varying mediump vec2 fposition;
|
||||||
|
@builtin@
|
||||||
|
|
||||||
|
// Top left corner
|
||||||
|
uniform mediump vec2 top_left;
|
||||||
|
|
||||||
|
// Top left corner with shadows included
|
||||||
|
uniform mediump vec2 full_top_left;
|
||||||
|
|
||||||
|
// Bottom right corner
|
||||||
|
uniform mediump vec2 bottom_right;
|
||||||
|
|
||||||
|
// Bottom right corner with shadows included
|
||||||
|
uniform mediump vec2 full_bottom_right;
|
||||||
|
|
||||||
|
// Rounding radius
|
||||||
|
const mediump float radius = 20.0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
mediump vec2 corner_dist = min(fposition - top_left, bottom_right - fposition);
|
||||||
|
if (max(corner_dist.x, corner_dist.y) < radius)
|
||||||
|
{
|
||||||
|
if (distance(corner_dist, vec2(radius, radius)) > radius)
|
||||||
|
{
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
highp vec2 uv = (fposition - full_top_left) / (full_bottom_right - full_top_left);
|
||||||
|
uv.y = 1.0 - uv.y;
|
||||||
|
gl_FragColor = get_pixel(uv);
|
||||||
|
})";
|
||||||
|
}
|
||||||
|
|
||||||
|
class rounded_corners_transformer_t : public wf::view_transformer_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t get_z_order() override
|
||||||
|
{
|
||||||
|
return wf::TRANSFORMER_2D - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wf::region_t transform_opaque_region(
|
||||||
|
wf::geometry_t box, wf::region_t region) override
|
||||||
|
{
|
||||||
|
(void)box;
|
||||||
|
(void)region;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
wf::pointf_t transform_point(
|
||||||
|
wf::geometry_t view, wf::pointf_t point) override
|
||||||
|
{
|
||||||
|
(void)view;
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
wf::pointf_t untransform_point(
|
||||||
|
wf::geometry_t view, wf::pointf_t point) override
|
||||||
|
{
|
||||||
|
(void)view;
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
wf::geometry_t get_bounding_box(wf::geometry_t bbox, wlr_box region) override
|
||||||
|
{
|
||||||
|
(void)bbox;
|
||||||
|
return wf::geometry_intersection(this->view->get_wm_geometry(), region);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<GLfloat> vertex_data;
|
||||||
|
void upload_data(wlr_box src_box)
|
||||||
|
{
|
||||||
|
auto geometry = view->get_wm_geometry();
|
||||||
|
float x = geometry.x, y = geometry.y,
|
||||||
|
w = geometry.width, h = geometry.height;
|
||||||
|
|
||||||
|
vertex_data = {
|
||||||
|
x, y + h,
|
||||||
|
x + w, y + h,
|
||||||
|
x + w, y,
|
||||||
|
x, y,
|
||||||
|
};
|
||||||
|
program.attrib_pointer("position", 2, 0, vertex_data.data(), GL_FLOAT);
|
||||||
|
|
||||||
|
program.uniform2f("top_left", x, y);
|
||||||
|
program.uniform2f("bottom_right", x + w, y + h);
|
||||||
|
program.uniform2f("full_top_left", src_box.x, src_box.y);
|
||||||
|
program.uniform2f("full_bottom_right",
|
||||||
|
src_box.x + src_box.width, src_box.y + src_box.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_with_damage(wf::texture_t src_tex, wlr_box src_box,
|
||||||
|
const wf::region_t& damage, const wf::framebuffer_t& target_fb) override
|
||||||
|
{
|
||||||
|
OpenGL::render_begin(target_fb);
|
||||||
|
|
||||||
|
program.use(src_tex.type);
|
||||||
|
program.set_active_texture(src_tex);
|
||||||
|
upload_data(src_box);
|
||||||
|
program.uniformMatrix4f("matrix", target_fb.get_orthographic_projection());
|
||||||
|
|
||||||
|
GL_CALL(glEnable(GL_BLEND));
|
||||||
|
GL_CALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
|
||||||
|
for (const auto& box : damage)
|
||||||
|
{
|
||||||
|
target_fb.logic_scissor(wlr_box_from_pixman_box(box));
|
||||||
|
GL_CALL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
GL_CALL(glDisable(GL_BLEND));
|
||||||
|
program.deactivate();
|
||||||
|
OpenGL::render_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
rounded_corners_transformer_t(wayfire_view view)
|
||||||
|
{
|
||||||
|
this->view = view;
|
||||||
|
|
||||||
|
OpenGL::render_begin();
|
||||||
|
program.compile(vertex_source, frag_source);
|
||||||
|
OpenGL::render_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~rounded_corners_transformer_t()
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wayfire_view view;
|
||||||
|
OpenGL::program_t program;
|
||||||
|
};
|
||||||
|
|
||||||
|
class wayfire_rounded_corners_t : public wf::plugin_interface_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void init() override
|
||||||
|
{
|
||||||
|
output->connect_signal("view-mapped", &on_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
wf::signal_connection_t on_map = [=] (wf::signal_data_t *data)
|
||||||
|
{
|
||||||
|
auto view = wf::get_signaled_view(data);
|
||||||
|
// Ignore panels, backgrounds, etc.
|
||||||
|
if (view->role == wf::VIEW_ROLE_TOPLEVEL)
|
||||||
|
{
|
||||||
|
view->add_transformer(
|
||||||
|
std::make_unique<rounded_corners_transformer_t>(view));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_WAYFIRE_PLUGIN(wayfire_rounded_corners_t);
|
Loading…
Reference in a new issue