mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
598 Commits
v1.7.8
...
v1.8.2-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
306b627090 | ||
|
|
90e7d7e112 | ||
|
|
7be79613b8 | ||
|
|
cf12d31875 | ||
|
|
32f92f7a90 | ||
|
|
392f4b44f0 | ||
|
|
a65ab1d5a7 | ||
|
|
57537ea10e | ||
|
|
51cbd977f0 | ||
|
|
392e88db34 | ||
|
|
0a0897ef28 | ||
|
|
5b193bad4b | ||
|
|
c647b0c65e | ||
|
|
9193720789 | ||
|
|
3208a77bf3 | ||
|
|
cbda307ebf | ||
|
|
0358862066 | ||
|
|
d901504ea9 | ||
|
|
4dc74776c1 | ||
|
|
71f13620d3 | ||
|
|
a914d3c534 | ||
|
|
242a55aa60 | ||
|
|
9045171ad7 | ||
|
|
e5797a57a7 | ||
|
|
3a571bbdb4 | ||
|
|
f40cc5ab54 | ||
|
|
60e614b10c | ||
|
|
f57b619097 | ||
|
|
4c9d432bd9 | ||
|
|
7b8dc38e88 | ||
|
|
bce7d37086 | ||
|
|
13b9b5c0c0 | ||
|
|
cf6e3ca087 | ||
|
|
bdf3552be6 | ||
|
|
26220f2b31 | ||
|
|
f2a1f0124d | ||
|
|
2b510d7a06 | ||
|
|
d07529feca | ||
|
|
6381f28847 | ||
|
|
af99e65876 | ||
|
|
6fa9249062 | ||
|
|
06d782279c | ||
|
|
88616df2e5 | ||
|
|
c51ac6048d | ||
|
|
30abdbccf8 | ||
|
|
66df065e31 | ||
|
|
ed25941c65 | ||
|
|
2c7787900f | ||
|
|
9308c96f95 | ||
|
|
4ffb6c5f75 | ||
|
|
b5ba8699f3 | ||
|
|
19ac2179fb | ||
|
|
1e6d51642c | ||
|
|
878813f968 | ||
|
|
d7e5855ebf | ||
|
|
a48219ecf2 | ||
|
|
995dccc726 | ||
|
|
0572b395ba | ||
|
|
6e08682a7f | ||
|
|
000ea8febd | ||
|
|
b02691cebd | ||
|
|
909fc98e1b | ||
|
|
53d138505a | ||
|
|
e655222d2f | ||
|
|
d096fc8acf | ||
|
|
48be4e765a | ||
|
|
841763326a | ||
|
|
2ed2aedb00 | ||
|
|
767a178bd1 | ||
|
|
ec610cd97b | ||
|
|
e027ba9c47 | ||
|
|
d350134c4f | ||
|
|
b8a58d0fce | ||
|
|
1d25d58c26 | ||
|
|
c85b159d46 | ||
|
|
77d4927e8b | ||
|
|
2bd8877be3 | ||
|
|
242e097e9b | ||
|
|
443c30890b | ||
|
|
61e606bedc | ||
|
|
bedb8ca191 | ||
|
|
35eea8bea5 | ||
|
|
66827755e7 | ||
|
|
85ef1ee21f | ||
|
|
e5d4574d3a | ||
|
|
a1347f67a1 | ||
|
|
c9da806c84 | ||
|
|
a45b1625fc | ||
|
|
1761d5da06 | ||
|
|
63749e281d | ||
|
|
11ac780caf | ||
|
|
31eb83223b | ||
|
|
7062a6e55d | ||
|
|
5e6b683cfb | ||
|
|
8e1945f768 | ||
|
|
0ae12c2b3d | ||
|
|
54563dc94c | ||
|
|
f81e4ec972 | ||
|
|
d7aa0b0ddb | ||
|
|
e098f414e4 | ||
|
|
f8f21815eb | ||
|
|
80e6a64e47 | ||
|
|
bb71b09452 | ||
|
|
4342480473 | ||
|
|
0b205019b6 | ||
|
|
ee519b7552 | ||
|
|
fae918be59 | ||
|
|
b77fe4ca12 | ||
|
|
3a0de7e24a | ||
|
|
44572dce7d | ||
|
|
ba6f01a109 | ||
|
|
9f55e162a3 | ||
|
|
d51a8accee | ||
|
|
cd411a5c36 | ||
|
|
fe7c827e30 | ||
|
|
cc80930e2b | ||
|
|
d20ce404ef | ||
|
|
2d269fb7f1 | ||
|
|
15bfb86eec | ||
|
|
8c5bb5969c | ||
|
|
a337b12877 | ||
|
|
4e05d24d1b | ||
|
|
5c94e23004 | ||
|
|
587c49f6b1 | ||
|
|
211688453c | ||
|
|
5e7a45d6da | ||
|
|
f72c72f4d4 | ||
|
|
028bab0320 | ||
|
|
ee2168b94d | ||
|
|
c4de658964 | ||
|
|
9fcf7eb27c | ||
|
|
6131a523dc | ||
|
|
93e40ee79c | ||
|
|
150a4797a4 | ||
|
|
745fa707dd | ||
|
|
09b93aa164 | ||
|
|
1bb042a661 | ||
|
|
32ad59de26 | ||
|
|
d594092675 | ||
|
|
7570ec9d39 | ||
|
|
3f73e000ee | ||
|
|
7df5182901 | ||
|
|
7c1c8f323c | ||
|
|
68d35dbeb1 | ||
|
|
7a163ef0cc | ||
|
|
b77467ca8f | ||
|
|
e8ec1a6ed4 | ||
|
|
bf2b6b3ac4 | ||
|
|
56581b416d | ||
|
|
a2f178b664 | ||
|
|
01ca3ae07f | ||
|
|
cc6803b358 | ||
|
|
33394f76d4 | ||
|
|
f0048d54b0 | ||
|
|
0cc1ebc021 | ||
|
|
3ad1cccb1d | ||
|
|
9f895879bf | ||
|
|
9db9ffd3e4 | ||
|
|
0ca53420d5 | ||
|
|
6932a42b0a | ||
|
|
b1e6845409 | ||
|
|
96f1a25bbd | ||
|
|
e7bb553d3b | ||
|
|
7f2c4a9e06 | ||
|
|
c620d0de05 | ||
|
|
04430c6dda | ||
|
|
0dfadf7c09 | ||
|
|
911e266e9a | ||
|
|
223942bf99 | ||
|
|
94f46c9059 | ||
|
|
fc443a8c2c | ||
|
|
e05f6102c2 | ||
|
|
d2d4b4cc23 | ||
|
|
c1c8f7b0f1 | ||
|
|
2353fdb400 | ||
|
|
e81cf74b39 | ||
|
|
e096b5ce83 | ||
|
|
3de008035a | ||
|
|
f026bbb454 | ||
|
|
5ef4caf8ab | ||
|
|
7788b33dc9 | ||
|
|
d9d557dcc5 | ||
|
|
2915617c5c | ||
|
|
0f34967648 | ||
|
|
0c9ada08a4 | ||
|
|
89246f3714 | ||
|
|
24913a5ef9 | ||
|
|
2289d085fa | ||
|
|
945fef8a5a | ||
|
|
928d2f78c3 | ||
|
|
04373b8658 | ||
|
|
044a3a29a6 | ||
|
|
2e747e72cf | ||
|
|
494000114c | ||
|
|
415f1ca3a4 | ||
|
|
750f59cb55 | ||
|
|
18589a498c | ||
|
|
15b0878a17 | ||
|
|
05c50b0a2e | ||
|
|
8062962d01 | ||
|
|
31bf873c20 | ||
|
|
6e85f82d7a | ||
|
|
c932871bb1 | ||
|
|
3c6a7c332a | ||
|
|
d45788a7b8 | ||
|
|
f49f7d65a5 | ||
|
|
9b6f9a0b18 | ||
|
|
afe033a6e1 | ||
|
|
4753ada7a9 | ||
|
|
5217718d7b | ||
|
|
ea42851c9b | ||
|
|
91e11f8e6f | ||
|
|
3545280e1d | ||
|
|
c70508edb1 | ||
|
|
de4cb9022b | ||
|
|
dfd90c3526 | ||
|
|
ff97817668 | ||
|
|
741dc1eb0b | ||
|
|
c33c21e174 | ||
|
|
75feb495ad | ||
|
|
2abde14a7c | ||
|
|
aeb568b41f | ||
|
|
e1ddd3bdbc | ||
|
|
f3f6bedf8e | ||
|
|
42a2126273 | ||
|
|
d87ea5713d | ||
|
|
5940231b76 | ||
|
|
d54cb307d5 | ||
|
|
2bb26b30dc | ||
|
|
696c7d59fd | ||
|
|
d27f7c25b3 | ||
|
|
5843c98153 | ||
|
|
d552c97599 | ||
|
|
a99280398b | ||
|
|
cb7f8e256e | ||
|
|
d621471eb2 | ||
|
|
ec587032b2 | ||
|
|
df098c2b2b | ||
|
|
5b5c4787e9 | ||
|
|
c4cfb3e711 | ||
|
|
b4075bed87 | ||
|
|
b7119b5756 | ||
|
|
4147fa4629 | ||
|
|
0ab83b301d | ||
|
|
ecbeb0d117 | ||
|
|
f928a399ae | ||
|
|
28900a9b63 | ||
|
|
fb6a4febb0 | ||
|
|
27fd2dad59 | ||
|
|
639f445f5e | ||
|
|
fa8649e671 | ||
|
|
fa444dd029 | ||
|
|
ba5fe1d161 | ||
|
|
9cfadbe6af | ||
|
|
0bcc5d37ab | ||
|
|
564ca27679 | ||
|
|
9fecf4b2f7 | ||
|
|
800ba9a325 | ||
|
|
b277353238 | ||
|
|
5eb4b9ad6f | ||
|
|
8ebab10cb0 | ||
|
|
fc99785314 | ||
|
|
af92a639be | ||
|
|
e1a232e7c8 | ||
|
|
6bf2ec4188 | ||
|
|
af329a9429 | ||
|
|
07840906dd | ||
|
|
ff023115f5 | ||
|
|
33dd5e26fb | ||
|
|
77a1c5d7fc | ||
|
|
9483f0fc14 | ||
|
|
c23b4a48ec | ||
|
|
76efee675f | ||
|
|
f6ac00532f | ||
|
|
a870799c32 | ||
|
|
787675ab08 | ||
|
|
ac55c358e9 | ||
|
|
53b0698ee2 | ||
|
|
073583ff3d | ||
|
|
19a7c7ac39 | ||
|
|
0d69738bd6 | ||
|
|
0301961c25 | ||
|
|
e18cdc185a | ||
|
|
d0c91daaed | ||
|
|
dc7cc6921e | ||
|
|
dae63d323c | ||
|
|
a19a229a59 | ||
|
|
589585a269 | ||
|
|
432b912c6a | ||
|
|
5819acfd3d | ||
|
|
0d312f3674 | ||
|
|
64c8ff62af | ||
|
|
2048a1a638 | ||
|
|
c34fb146f6 | ||
|
|
c39f5f1fad | ||
|
|
9a7d8a0511 | ||
|
|
6bded6bf7b | ||
|
|
fa4d52f042 | ||
|
|
618f8a9d06 | ||
|
|
ddb1d92c77 | ||
|
|
1cb13be65f | ||
|
|
d6bab3043c | ||
|
|
e66341ec59 | ||
|
|
a01abd0fee | ||
|
|
2d771674bb | ||
|
|
74cb673ce1 | ||
|
|
b9f0131165 | ||
|
|
13d363d1f1 | ||
|
|
9f60673e4b | ||
|
|
549c30f9b2 | ||
|
|
59cadf9e4b | ||
|
|
bca71fcfc1 | ||
|
|
1430faa2fd | ||
|
|
8493d5707e | ||
|
|
92d0772eba | ||
|
|
6ebd00267e | ||
|
|
894bcdf749 | ||
|
|
f256967414 | ||
|
|
64c447bf04 | ||
|
|
2c56b67ea5 | ||
|
|
10ab870237 | ||
|
|
cc9771a3d0 | ||
|
|
e6733b4b23 | ||
|
|
0694334487 | ||
|
|
c51e3c2882 | ||
|
|
6442e6b5e8 | ||
|
|
38342fbe48 | ||
|
|
f293e1422b | ||
|
|
20325b9952 | ||
|
|
c265ea21c2 | ||
|
|
fbfd781426 | ||
|
|
195cb91721 | ||
|
|
511e82de67 | ||
|
|
8e9b98360a | ||
|
|
6ba3ee3950 | ||
|
|
54bd60d657 | ||
|
|
4fb800a899 | ||
|
|
a81ea1ffde | ||
|
|
c56d8b4fe9 | ||
|
|
5bb7b4bb42 | ||
|
|
4b1e2b42a4 | ||
|
|
c784968e85 | ||
|
|
6b010614e2 | ||
|
|
14eea98566 | ||
|
|
c2ab4f711f | ||
|
|
1630f14b99 | ||
|
|
64d9e5b861 | ||
|
|
346a4bee0b | ||
|
|
db0aeaa26e | ||
|
|
7cd64f1bd1 | ||
|
|
5978775ce1 | ||
|
|
a936430fd5 | ||
|
|
b54804d449 | ||
|
|
74c970c25f | ||
|
|
8fe675e56c | ||
|
|
cc666c727f | ||
|
|
178b39b5a8 | ||
|
|
6c201fcae4 | ||
|
|
39a366cf76 | ||
|
|
0550a4a9b8 | ||
|
|
7f4b74f8c6 | ||
|
|
e58ba1dc8e | ||
|
|
f0f17fffd8 | ||
|
|
4febbec102 | ||
|
|
b2f3625eaa | ||
|
|
593ae7bf0e | ||
|
|
5510d8cfb1 | ||
|
|
68e0fbfd60 | ||
|
|
9337e29482 | ||
|
|
56233054ae | ||
|
|
6e6b097968 | ||
|
|
a7bae32527 | ||
|
|
c6918966c2 | ||
|
|
93a8e75238 | ||
|
|
66a5ac4d67 | ||
|
|
e1c4962312 | ||
|
|
55f2b524e7 | ||
|
|
75b2915fee | ||
|
|
6a285e2e76 | ||
|
|
c4634f7e98 | ||
|
|
87d4666648 | ||
|
|
deb7ccbef3 | ||
|
|
bb153ee79e | ||
|
|
dc43dc2a13 | ||
|
|
65eb4e1994 | ||
|
|
6717f0d2bb | ||
|
|
6a93052f7d | ||
|
|
7ecac42214 | ||
|
|
fdfbf3abfa | ||
|
|
a44c2d5dcc | ||
|
|
f984bd2ff5 | ||
|
|
eca7ff986c | ||
|
|
bf07c5aebd | ||
|
|
e64d4e5bd7 | ||
|
|
15d2cfe458 | ||
|
|
88b3109137 | ||
|
|
5cb58cd42f | ||
|
|
485b9099f1 | ||
|
|
cd5cd25f74 | ||
|
|
18e7354b4a | ||
|
|
9605e6cb40 | ||
|
|
d3f30e7a9c | ||
|
|
1f604c0826 | ||
|
|
2bfc2be8c9 | ||
|
|
d233fc044a | ||
|
|
b4428e7e41 | ||
|
|
8b55e6e2f5 | ||
|
|
94ab1c790f | ||
|
|
de67e42fc9 | ||
|
|
136857952e | ||
|
|
cd42133651 | ||
|
|
0c93e4b8d7 | ||
|
|
f954b60119 | ||
|
|
565ece6986 | ||
|
|
f0680587fa | ||
|
|
f17bd040ad | ||
|
|
b1011768e5 | ||
|
|
b6787dbbb3 | ||
|
|
1731359a17 | ||
|
|
f2c0d1f0c5 | ||
|
|
db081d95d5 | ||
|
|
a50e36d256 | ||
|
|
6c60c6ca76 | ||
|
|
2c1984b6ed | ||
|
|
dede3d6213 | ||
|
|
70fd42808e | ||
|
|
19323c88f9 | ||
|
|
c0331673da | ||
|
|
eeb2e58ad8 | ||
|
|
39c2a4721b | ||
|
|
94dd068e15 | ||
|
|
8695672082 | ||
|
|
15db4ee450 | ||
|
|
81f7b422e4 | ||
|
|
766b604de5 | ||
|
|
ac6a44f0ac | ||
|
|
2b9b186fd1 | ||
|
|
0cfae1cc2b | ||
|
|
340431750b | ||
|
|
4bc4a0c45b | ||
|
|
01f549628f | ||
|
|
9c552644d8 | ||
|
|
f6792c0232 | ||
|
|
ecff620528 | ||
|
|
f908678e8e | ||
|
|
32121b9c38 | ||
|
|
c4d1fb929c | ||
|
|
65908bbb87 | ||
|
|
44481db1ee | ||
|
|
5543bfc278 | ||
|
|
d4bbd7c7ab | ||
|
|
814702f5b8 | ||
|
|
6191e6e787 | ||
|
|
9120774c00 | ||
|
|
78c87d4bd3 | ||
|
|
5f82168213 | ||
|
|
a84d49fe5c | ||
|
|
2ec223ba11 | ||
|
|
35b2bc6b51 | ||
|
|
68250d80cd | ||
|
|
2edf4da859 | ||
|
|
7741a0e6ad | ||
|
|
25c0cf0612 | ||
|
|
9487222726 | ||
|
|
60b363fa3b | ||
|
|
90fbe5c06c | ||
|
|
7226adee29 | ||
|
|
27c1612f44 | ||
|
|
fb6759b5e0 | ||
|
|
eabbac4ca1 | ||
|
|
d943519fb4 | ||
|
|
9d2aa6f1c7 | ||
|
|
9f8f95f4c9 | ||
|
|
924a345fac | ||
|
|
59238a915e | ||
|
|
03d15809be | ||
|
|
778772710a | ||
|
|
fb02343ec0 | ||
|
|
dc6e451010 | ||
|
|
1f71a2e94c | ||
|
|
b407834ed7 | ||
|
|
f1036f7305 | ||
|
|
c3e0e4682d | ||
|
|
a0fd37c8a3 | ||
|
|
23b35af7f2 | ||
|
|
ddefc08ec5 | ||
|
|
f79a90161c | ||
|
|
29dc06c89d | ||
|
|
5737f8b74e | ||
|
|
bbd1b325fb | ||
|
|
152d573fbd | ||
|
|
adaec2d32b | ||
|
|
b6f0d04813 | ||
|
|
fe0a96200d | ||
|
|
c6ba812d79 | ||
|
|
6ab0a8a287 | ||
|
|
90ec61fbe9 | ||
|
|
ba0c43e1fc | ||
|
|
1d10654a22 | ||
|
|
76d46ce509 | ||
|
|
5ef668de64 | ||
|
|
ca4a6e4692 | ||
|
|
1d132565c9 | ||
|
|
7d1a49db48 | ||
|
|
9945fc5148 | ||
|
|
ad33e569d6 | ||
|
|
34fff57646 | ||
|
|
4fc2b3e642 | ||
|
|
4bb95acc2b | ||
|
|
c7cf844bcd | ||
|
|
ba9b8719ac | ||
|
|
f4411889a9 | ||
|
|
627eb30409 | ||
|
|
b8b7d0ab1a | ||
|
|
45db999593 | ||
|
|
4d9f309888 | ||
|
|
e2fe95894f | ||
|
|
e16e1e2854 | ||
|
|
90574160db | ||
|
|
b997c2ffc1 | ||
|
|
f824b1e9d4 | ||
|
|
48821a6d2a | ||
|
|
d09cab2e21 | ||
|
|
ffbb16e854 | ||
|
|
30fafc2772 | ||
|
|
9b8a77f0d8 | ||
|
|
d322769de8 | ||
|
|
faaeab7e4a | ||
|
|
567646e624 | ||
|
|
adddff3ee2 | ||
|
|
99e57f9072 | ||
|
|
6415f181ca | ||
|
|
bd971b6371 | ||
|
|
0adc887b32 | ||
|
|
7c7300ff82 | ||
|
|
bda5e4efcb | ||
|
|
cc350efbd8 | ||
|
|
49fbb52b01 | ||
|
|
3d700ee49f | ||
|
|
c7f2e2731c | ||
|
|
1126719e7f | ||
|
|
a20f633272 | ||
|
|
fb7bd8f11e | ||
|
|
7a4ca08a8d | ||
|
|
3939359354 | ||
|
|
1709b8e39d | ||
|
|
a419fe75ca | ||
|
|
4ba4fe4f62 | ||
|
|
3062027bab | ||
|
|
78f11df6e4 | ||
|
|
3405596983 | ||
|
|
d6fbf5f1bb | ||
|
|
6d16eb81d2 | ||
|
|
6a872dd938 | ||
|
|
796664ef1c | ||
|
|
10f2c80162 | ||
|
|
3d33da7696 | ||
|
|
60c0bf1636 | ||
|
|
646a8eb753 | ||
|
|
8a2c35023f | ||
|
|
ba5fa2c8b1 | ||
|
|
235ae0989f | ||
|
|
837a34cf71 | ||
|
|
01f31edb95 | ||
|
|
cfe914ff83 | ||
|
|
06f4c1b337 | ||
|
|
3815ed8af4 | ||
|
|
c1a40fbd98 | ||
|
|
bb1627a69b | ||
|
|
ad90de0c82 | ||
|
|
0cd99d9815 | ||
|
|
6956f2fc69 | ||
|
|
fd6aeda6f6 | ||
|
|
b4bb00843b | ||
|
|
4c48908a31 | ||
|
|
404589d9b5 | ||
|
|
d913b53fea | ||
|
|
c6289ef219 | ||
|
|
47d652b5a2 | ||
|
|
7bfece1144 | ||
|
|
a55015d63d | ||
|
|
a5dfb09037 | ||
|
|
ae5c8e63d9 | ||
|
|
ebe058e7cb | ||
|
|
96dd9b9ab8 | ||
|
|
fdd0d67fd3 | ||
|
|
a16c4167eb | ||
|
|
1a6f0ae437 | ||
|
|
df66223f4c | ||
|
|
39c46a9b75 | ||
|
|
e6abfa959a | ||
|
|
a8759a3176 | ||
|
|
0736de1e8d | ||
|
|
12dbcfa2ea | ||
|
|
a84fa0eecb | ||
|
|
517184b89b | ||
|
|
5f2dd2ef6c | ||
|
|
1b8963ff6e |
@@ -6,33 +6,265 @@ jobs:
|
||||
- image: electronbuilds/electron:0.0.3
|
||||
environment:
|
||||
TARGET_ARCH: arm
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run: script/cibuild
|
||||
|
||||
- run:
|
||||
name: Setup for headless testing
|
||||
command: sh -e /etc/init.d/xvfb start
|
||||
- run:
|
||||
name: Check for release
|
||||
command: |
|
||||
MESSAGE="$(git log --format=%B -n 1 HEAD)"
|
||||
case ${MESSAGE} in
|
||||
Bump* ) echo 'export ELECTRON_RELEASE=1' >> $BASH_ENV
|
||||
esac
|
||||
- run:
|
||||
name: Bootstrap
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Bootstrapping Electron for release build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||
else
|
||||
echo 'Bootstrapping Electron for debug build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||
fi
|
||||
- run: npm run lint
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Building Electron for release'
|
||||
script/build.py -c R
|
||||
else
|
||||
echo 'Building Electron for debug'
|
||||
script/build.py -c D
|
||||
fi
|
||||
- run:
|
||||
name: Create distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Creating Electron release distribution'
|
||||
script/create-dist.py
|
||||
else
|
||||
echo 'Skipping create distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Upload distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution'
|
||||
script/upload.py
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
electron-linux-arm64:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.3
|
||||
environment:
|
||||
TARGET_ARCH: arm64
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Setup for headless testing
|
||||
command: sh -e /etc/init.d/xvfb start
|
||||
- run:
|
||||
name: Check for release
|
||||
command: |
|
||||
MESSAGE="$(git log --format=%B -n 1 HEAD)"
|
||||
case ${MESSAGE} in
|
||||
Bump* ) echo 'export ELECTRON_RELEASE=1' >> $BASH_ENV
|
||||
esac
|
||||
- run:
|
||||
name: Bootstrap
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Bootstrapping Electron for release build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||
else
|
||||
echo 'Bootstrapping Electron for debug build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||
fi
|
||||
- run: npm run lint
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Building Electron for release'
|
||||
script/build.py -c R
|
||||
else
|
||||
echo 'Building Electron for debug'
|
||||
script/build.py -c D
|
||||
fi
|
||||
- run:
|
||||
name: Create distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Creating Electron release distribution'
|
||||
script/create-dist.py
|
||||
else
|
||||
echo 'Skipping create distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Upload distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution'
|
||||
script/upload.py
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
electron-linux-ia32:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.3
|
||||
environment:
|
||||
TARGET_ARCH: ia32
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run: script/cibuild
|
||||
- run:
|
||||
name: Setup for headless testing
|
||||
command: sh -e /etc/init.d/xvfb start
|
||||
- run:
|
||||
name: Check for release
|
||||
command: |
|
||||
MESSAGE="$(git log --format=%B -n 1 HEAD)"
|
||||
case ${MESSAGE} in
|
||||
Bump* ) echo 'export ELECTRON_RELEASE=1' >> $BASH_ENV
|
||||
esac
|
||||
- run:
|
||||
name: Bootstrap
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Bootstrapping Electron for release build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||
else
|
||||
echo 'Bootstrapping Electron for debug build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||
fi
|
||||
- run: npm run lint
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Building Electron for release'
|
||||
script/build.py -c R
|
||||
else
|
||||
echo 'Building Electron for debug'
|
||||
script/build.py -c D
|
||||
fi
|
||||
- run:
|
||||
name: Create distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Creating Electron release distribution'
|
||||
script/create-dist.py
|
||||
else
|
||||
echo 'Skipping create distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Upload distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution'
|
||||
script/upload.py
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
|
||||
electron-linux-x64:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.3
|
||||
environment:
|
||||
TARGET_ARCH: x64
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run: script/cibuild
|
||||
- run:
|
||||
name: Setup for headless testing
|
||||
command: sh -e /etc/init.d/xvfb start
|
||||
- run:
|
||||
name: Check for release
|
||||
command: |
|
||||
MESSAGE="$(git log --format=%B -n 1 HEAD)"
|
||||
case ${MESSAGE} in
|
||||
Bump* ) echo 'export ELECTRON_RELEASE=1' >> $BASH_ENV
|
||||
esac
|
||||
- run:
|
||||
name: Bootstrap
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Bootstrapping Electron for release build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||
else
|
||||
echo 'Bootstrapping Electron for debug build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||
fi
|
||||
- run: npm run lint
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Building Electron for release'
|
||||
script/build.py -c R
|
||||
else
|
||||
echo 'Building Electron for debug'
|
||||
script/build.py -c D
|
||||
fi
|
||||
- run:
|
||||
name: Create distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Creating Electron release distribution'
|
||||
script/create-dist.py
|
||||
else
|
||||
echo 'Skipping create distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Upload distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution'
|
||||
script/upload.py
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Test
|
||||
environment:
|
||||
MOCHA_FILE: junit/test-results.xml
|
||||
MOCHA_REPORTER: mocha-junit-reporter
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
echo 'Testing Electron debug build'
|
||||
mkdir junit
|
||||
script/test.py --ci --rebuild_native_modules
|
||||
else
|
||||
echo 'Skipping testing on release build'
|
||||
fi
|
||||
- run:
|
||||
name: Verify FFmpeg
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
echo 'Verifying ffmpeg on debug build'
|
||||
script/verify-ffmpeg.py
|
||||
else
|
||||
echo 'Skipping verify ffmpeg on release build'
|
||||
fi
|
||||
- store_test_results:
|
||||
path: junit
|
||||
- store_artifacts:
|
||||
path: junit
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build-arm:
|
||||
jobs:
|
||||
- electron-linux-arm
|
||||
build-arm64:
|
||||
jobs:
|
||||
- electron-linux-arm64
|
||||
build-ia32:
|
||||
jobs:
|
||||
- electron-linux-ia32
|
||||
|
||||
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!tools/xvfb-init.sh
|
||||
21
.github/CODEOWNERS
vendored
Normal file
21
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Order is important. The LAST matching pattern has the MOST precedence.
|
||||
# gitignore style patterns are used, not globs.
|
||||
# https://help.github.com/articles/about-codeowners
|
||||
# https://git-scm.com/docs/gitignore
|
||||
|
||||
# Everything that falls through the cracks:
|
||||
* @electron/reviewers
|
||||
|
||||
# filename patterns
|
||||
*browser_view* @electron/browserview
|
||||
*notification* @electron/notifications
|
||||
*pdf* @electron/printing
|
||||
*printing* @electron/printing
|
||||
*updater* @electron/updater
|
||||
|
||||
# directories
|
||||
/.github/ @electron/hubbers
|
||||
/default_app/ @electron/docs
|
||||
/docs/ @electron/docs
|
||||
/docs-translations/ @electron/i18n
|
||||
/npm/ @electron/hubbers
|
||||
29
.github/config.yml
vendored
Normal file
29
.github/config.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
|
||||
|
||||
# Comment to be posted to on first time issues
|
||||
newIssueWelcomeComment: |
|
||||
👋 Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.
|
||||
|
||||
To help make it easier for us to investigate your issue, please follow the [contributing guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md#submitting-issues).
|
||||
|
||||
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
|
||||
|
||||
# Comment to be posted to on PRs from first time contributors in your repository
|
||||
newPRWelcomeComment: |
|
||||
💖 Thanks for opening this pull request! 💖
|
||||
|
||||
Here is a list of things that will help get it across the finish line:
|
||||
- Follow the JavaScript, C++, and Python [coding style](https://github.com/electron/electron/blob/master/docs/development/coding-style.md).
|
||||
- Run `npm run lint` locally to catch formatting errors earlier.
|
||||
- Document any user-facing changes you've made following the [documentation styleguide](https://github.com/electron/electron/blob/master/docs/styleguide.md).
|
||||
- Include tests when adding/changing behavior.
|
||||
- Include screenshots and animated GIFs whenever possible.
|
||||
We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.
|
||||
|
||||
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
|
||||
|
||||
# Comment to be posted to on pull requests merged by a first time user
|
||||
firstPRMergeComment: >
|
||||
Congrats on merging your first pull request! 🎉🎉🎉
|
||||
|
||||
# It is recommend to include as many gifs and emojis as possiblec
|
||||
25
.github/stale.yml
vendored
Normal file
25
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 45
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- fixme/bug
|
||||
- fixme/crash
|
||||
- fixme/regression
|
||||
- fixme/security
|
||||
- blocked
|
||||
- blocking-stable
|
||||
- needs-review
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity and is not currently prioritized. It will be closed
|
||||
in a week if no further activity occurs :)
|
||||
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
If you still think this issue is relevant, please ping a maintainer or
|
||||
leave a comment!
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
.DS_Store
|
||||
.env
|
||||
.gclient_done
|
||||
.npmrc
|
||||
.tags*
|
||||
.vs/
|
||||
@@ -14,7 +15,6 @@
|
||||
*.vcxproj.filters
|
||||
*.vcxproj.user
|
||||
*.xcodeproj
|
||||
node_modules/
|
||||
/.idea/
|
||||
/brightray/brightray.opensdf
|
||||
/brightray/brightray.sdf
|
||||
@@ -41,3 +41,5 @@ node_modules/
|
||||
/vendor/node/deps/node-inspect/.npmrc
|
||||
/vendor/npm/
|
||||
/vendor/python_26/
|
||||
node_modules/
|
||||
SHASUMS256.txt
|
||||
|
||||
@@ -1 +1 @@
|
||||
v7.9.0
|
||||
v8.2.1
|
||||
|
||||
@@ -5,7 +5,7 @@ notifications:
|
||||
|
||||
before_install:
|
||||
- export BOTO_CONFIG=/dev/null
|
||||
|
||||
|
||||
language: node_js
|
||||
node_js:
|
||||
- "4"
|
||||
@@ -22,6 +22,8 @@ matrix:
|
||||
env: TARGET_ARCH=arm
|
||||
- os: linux
|
||||
env: TARGET_ARCH=ia32
|
||||
- os: linux
|
||||
env: TARGET_ARCH=arm64
|
||||
allow_failures:
|
||||
- os: osx
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ propose changes to this document in a pull request.
|
||||
|
||||
## Submitting Issues
|
||||
|
||||
### Creating Issues
|
||||
* You can create an issue [here](https://github.com/electron/electron/issues/new),
|
||||
but before doing that please read the notes below and include as many details as
|
||||
possible with your report. If you can, please include:
|
||||
@@ -27,6 +28,15 @@ possible with your report. If you can, please include:
|
||||
* Perform a [cursory search](https://github.com/electron/electron/issues?utf8=✓&q=is%3Aissue+)
|
||||
to see if a similar issue has already been submitted
|
||||
|
||||
### Issue Maintenance and Closure
|
||||
* If an issue is inactive for 45 days (no activity of any kind), it will be
|
||||
marked for closure with `stale`.
|
||||
* If after this label is applied, no further activity occurs in the next 7 days,
|
||||
the issue will be closed.
|
||||
* If an issue has been closed and you still feel it's relevant, feel free to
|
||||
ping a maintainer or add a comment!
|
||||
|
||||
|
||||
## Submitting Pull Requests
|
||||
|
||||
* Include screenshots and animated GIFs in your pull request whenever possible.
|
||||
|
||||
18
Dockerfile
Normal file
18
Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
FROM electronbuilds/libchromiumcontent:0.0.4
|
||||
|
||||
USER root
|
||||
|
||||
# Set up HOME directory
|
||||
ENV HOME=/home
|
||||
RUN chmod a+rwx /home
|
||||
|
||||
# Install node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
||||
RUN apt-get update && apt-get install -y --force-yes nodejs
|
||||
|
||||
# Install wget used by crash reporter
|
||||
RUN apt-get install -y --force-yes wget
|
||||
|
||||
# Add xvfb init script
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
17
Dockerfile.circleci
Normal file
17
Dockerfile.circleci
Normal file
@@ -0,0 +1,17 @@
|
||||
FROM electronbuilds/libchromiumcontent:0.0.4
|
||||
|
||||
USER root
|
||||
|
||||
# Install node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
||||
RUN apt-get update && apt-get install -y --force-yes nodejs
|
||||
|
||||
# Install wget used by crash reporter
|
||||
RUN apt-get install -y --force-yes wget
|
||||
|
||||
# Add xvfb init script
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
USER builduser
|
||||
WORKDIR /home/builduser
|
||||
@@ -9,6 +9,7 @@
|
||||
#if defined(OS_WIN)
|
||||
#include <windows.h> // windows.h must be included first
|
||||
|
||||
#include <atlbase.h> // ensures that ATL statics like `_AtlWinModule` are initialized (it's an issue in static debug build)
|
||||
#include <shellapi.h>
|
||||
#include <shellscalingapi.h>
|
||||
#include <tchar.h>
|
||||
@@ -34,7 +35,7 @@
|
||||
|
||||
namespace {
|
||||
|
||||
const char* kRunAsNode = "ELECTRON_RUN_AS_NODE";
|
||||
const auto kRunAsNode = "ELECTRON_RUN_AS_NODE";
|
||||
|
||||
bool IsEnvSet(const char* name) {
|
||||
#if defined(OS_WIN)
|
||||
@@ -56,6 +57,29 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
|
||||
bool run_as_node = IsEnvSet(kRunAsNode);
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Don't display assert dialog boxes in CI test runs
|
||||
static const auto kCI = "ELECTRON_CI";
|
||||
bool is_ci = IsEnvSet(kCI);
|
||||
if (!is_ci) {
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
if (!_wcsicmp(wargv[i], L"--ci")) {
|
||||
is_ci = true;
|
||||
_putenv_s(kCI, "1"); // set flag for child processes
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_ci) {
|
||||
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
|
||||
|
||||
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
|
||||
|
||||
_set_error_mode(_OUT_TO_STDERR);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Make sure the output is printed to console.
|
||||
if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE"))
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/app/uv_task_runner.h"
|
||||
|
||||
#include "base/stl_util.h"
|
||||
@@ -19,13 +21,13 @@ UvTaskRunner::~UvTaskRunner() {
|
||||
}
|
||||
|
||||
bool UvTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::OnceClosure task,
|
||||
base::TimeDelta delay) {
|
||||
auto* timer = new uv_timer_t;
|
||||
timer->data = this;
|
||||
uv_timer_init(loop_, timer);
|
||||
uv_timer_start(timer, UvTaskRunner::OnTimeout, delay.InMilliseconds(), 0);
|
||||
tasks_[timer] = task;
|
||||
tasks_[timer] = std::move(task);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -35,9 +37,9 @@ bool UvTaskRunner::RunsTasksOnCurrentThread() const {
|
||||
|
||||
bool UvTaskRunner::PostNonNestableDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::OnceClosure task,
|
||||
base::TimeDelta delay) {
|
||||
return PostDelayedTask(from_here, task, delay);
|
||||
return PostDelayedTask(from_here, std::move(task), delay);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -46,7 +48,7 @@ void UvTaskRunner::OnTimeout(uv_timer_t* timer) {
|
||||
if (!ContainsKey(self->tasks_, timer))
|
||||
return;
|
||||
|
||||
self->tasks_[timer].Run();
|
||||
std::move(self->tasks_[timer]).Run();
|
||||
self->tasks_.erase(timer);
|
||||
uv_timer_stop(timer);
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(timer), UvTaskRunner::OnClose);
|
||||
|
||||
@@ -21,12 +21,12 @@ class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||
|
||||
// base::SingleThreadTaskRunner:
|
||||
bool PostDelayedTask(const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::OnceClosure task,
|
||||
base::TimeDelta delay) override;
|
||||
bool RunsTasksOnCurrentThread() const override;
|
||||
bool PostNonNestableDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::OnceClosure task,
|
||||
base::TimeDelta delay) override;
|
||||
|
||||
private:
|
||||
@@ -35,7 +35,7 @@ class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||
|
||||
uv_loop_t* loop_;
|
||||
|
||||
std::map<uv_timer_t*, base::Closure> tasks_;
|
||||
std::map<uv_timer_t*, base::OnceClosure> tasks_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(UvTaskRunner);
|
||||
};
|
||||
|
||||
@@ -54,6 +54,10 @@
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "atom/browser/ui/cocoa/atom_bundle_mover.h"
|
||||
#endif
|
||||
|
||||
using atom::Browser;
|
||||
|
||||
namespace mate {
|
||||
@@ -371,6 +375,8 @@ int GetPathConstant(const std::string& name) {
|
||||
return brightray::DIR_CACHE;
|
||||
else if (name == "userCache")
|
||||
return brightray::DIR_USER_CACHE;
|
||||
else if (name == "logs")
|
||||
return brightray::DIR_APP_LOGS;
|
||||
else if (name == "home")
|
||||
return base::DIR_HOME;
|
||||
else if (name == "temp")
|
||||
@@ -586,6 +592,18 @@ void App::OnAccessibilitySupportChanged() {
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void App::OnWillContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type) {
|
||||
*prevent_default = Emit("will-continue-activity", type);
|
||||
}
|
||||
|
||||
void App::OnDidFailToContinueUserActivity(
|
||||
const std::string& type,
|
||||
const std::string& error) {
|
||||
Emit("continue-activity-error", type, error);
|
||||
}
|
||||
|
||||
void App::OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
@@ -593,10 +611,22 @@ void App::OnContinueUserActivity(
|
||||
*prevent_default = Emit("continue-activity", type, user_info);
|
||||
}
|
||||
|
||||
void App::OnUserActivityWasContinued(
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
Emit("activity-was-continued", type, user_info);
|
||||
}
|
||||
|
||||
void App::OnUpdateUserActivityState(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
*prevent_default = Emit("update-activity-state", type, user_info);
|
||||
}
|
||||
|
||||
void App::OnNewWindowForTab() {
|
||||
Emit("new-window-for-tab");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void App::OnLogin(LoginHandler* login_handler,
|
||||
@@ -875,6 +905,16 @@ bool App::IsAccessibilitySupportEnabled() {
|
||||
return ax_state->IsAccessibleBrowser();
|
||||
}
|
||||
|
||||
void App::SetAccessibilitySupportEnabled(bool enabled) {
|
||||
auto ax_state = content::BrowserAccessibilityState::GetInstance();
|
||||
if (enabled) {
|
||||
ax_state->OnScreenReaderDetected();
|
||||
} else {
|
||||
ax_state->DisableAccessibility();
|
||||
}
|
||||
Browser::Get()->OnAccessibilitySupportChanged();
|
||||
}
|
||||
|
||||
Browser::LoginItemSettings App::GetLoginItemSettings(mate::Arguments* args) {
|
||||
Browser::LoginItemSettings options;
|
||||
args->GetNext(&options);
|
||||
@@ -1078,6 +1118,16 @@ void App::EnableMixedSandbox(mate::Arguments* args) {
|
||||
command_line->AppendSwitch(switches::kEnableMixedSandbox);
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool App::MoveToApplicationsFolder(mate::Arguments* args) {
|
||||
return ui::cocoa::AtomBundleMover::Move(args);
|
||||
}
|
||||
|
||||
bool App::IsInApplicationsFolder() {
|
||||
return ui::cocoa::AtomBundleMover::IsCurrentAppInApplicationsFolder();
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
mate::Handle<App> App::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new App(isolate));
|
||||
@@ -1121,6 +1171,10 @@ void App::BuildPrototype(
|
||||
base::Bind(&Browser::SetUserActivity, browser))
|
||||
.SetMethod("getCurrentActivityType",
|
||||
base::Bind(&Browser::GetCurrentActivityType, browser))
|
||||
.SetMethod("invalidateCurrentActivity",
|
||||
base::Bind(&Browser::InvalidateCurrentActivity, browser))
|
||||
.SetMethod("updateCurrentActivity",
|
||||
base::Bind(&Browser::UpdateCurrentActivity, browser))
|
||||
.SetMethod("setAboutPanelOptions",
|
||||
base::Bind(&Browser::SetAboutPanelOptions, browser))
|
||||
#endif
|
||||
@@ -1147,6 +1201,8 @@ void App::BuildPrototype(
|
||||
.SetMethod("relaunch", &App::Relaunch)
|
||||
.SetMethod("isAccessibilitySupportEnabled",
|
||||
&App::IsAccessibilitySupportEnabled)
|
||||
.SetMethod("setAccessibilitySupportEnabled",
|
||||
&App::SetAccessibilitySupportEnabled)
|
||||
.SetMethod("disableHardwareAcceleration",
|
||||
&App::DisableHardwareAcceleration)
|
||||
.SetMethod("disableDomainBlockingFor3DAPIs",
|
||||
@@ -1156,6 +1212,10 @@ void App::BuildPrototype(
|
||||
.SetMethod("getGPUFeatureStatus", &App::GetGPUFeatureStatus)
|
||||
.SetMethod("enableMixedSandbox", &App::EnableMixedSandbox)
|
||||
// TODO(juturu): Remove in 2.0, deprecate before then with warnings
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("moveToApplicationsFolder", &App::MoveToApplicationsFolder)
|
||||
.SetMethod("isInApplicationsFolder", &App::IsInApplicationsFolder)
|
||||
#endif
|
||||
.SetMethod("getAppMemoryInfo", &App::GetAppMetrics);
|
||||
}
|
||||
|
||||
|
||||
@@ -115,11 +115,23 @@ class App : public AtomBrowserClient::Delegate,
|
||||
void OnAccessibilitySupportChanged() override;
|
||||
void OnPreMainMessageLoopRun() override;
|
||||
#if defined(OS_MACOSX)
|
||||
void OnWillContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type) override;
|
||||
void OnDidFailToContinueUserActivity(
|
||||
const std::string& type,
|
||||
const std::string& error) override;
|
||||
void OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) override;
|
||||
|
||||
void OnUserActivityWasContinued(
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) override;
|
||||
void OnUpdateUserActivityState(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) override;
|
||||
void OnNewWindowForTab() override;
|
||||
#endif
|
||||
|
||||
@@ -173,6 +185,7 @@ class App : public AtomBrowserClient::Delegate,
|
||||
void DisableHardwareAcceleration(mate::Arguments* args);
|
||||
void DisableDomainBlockingFor3DAPIs(mate::Arguments* args);
|
||||
bool IsAccessibilitySupportEnabled();
|
||||
void SetAccessibilitySupportEnabled(bool enabled);
|
||||
Browser::LoginItemSettings GetLoginItemSettings(mate::Arguments* args);
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void ImportCertificate(const base::DictionaryValue& options,
|
||||
@@ -185,6 +198,11 @@ class App : public AtomBrowserClient::Delegate,
|
||||
v8::Local<v8::Value> GetGPUFeatureStatus(v8::Isolate* isolate);
|
||||
void EnableMixedSandbox(mate::Arguments* args);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool MoveToApplicationsFolder(mate::Arguments* args);
|
||||
bool IsInApplicationsFolder();
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Get the current Jump List settings.
|
||||
v8::Local<v8::Value> GetJumpListSettings();
|
||||
|
||||
@@ -212,6 +212,7 @@ struct Converter<atom::VerifyRequestParams> {
|
||||
dict.Set("hostname", val.hostname);
|
||||
dict.Set("certificate", val.certificate);
|
||||
dict.Set("verificationResult", val.default_result);
|
||||
dict.Set("errorCode", val.error_code);
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
@@ -433,6 +434,7 @@ void DownloadIdCallback(content::DownloadManager* download_manager,
|
||||
content::DownloadItem::INTERRUPTED,
|
||||
content::DownloadDangerType::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
content::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, false,
|
||||
base::Time(), false,
|
||||
std::vector<content::DownloadItem::ReceivedSlice>());
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ void SystemPreferences::BuildPrototype(
|
||||
&SystemPreferences::UnsubscribeLocalNotification)
|
||||
.SetMethod("getUserDefault", &SystemPreferences::GetUserDefault)
|
||||
.SetMethod("setUserDefault", &SystemPreferences::SetUserDefault)
|
||||
.SetMethod("removeUserDefault", &SystemPreferences::RemoveUserDefault)
|
||||
.SetMethod("isSwipeTrackingFromScrollEventsEnabled",
|
||||
&SystemPreferences::IsSwipeTrackingFromScrollEventsEnabled)
|
||||
#endif
|
||||
|
||||
@@ -76,6 +76,7 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||
void SetUserDefault(const std::string& name,
|
||||
const std::string& type,
|
||||
mate::Arguments* args);
|
||||
void RemoveUserDefault(const std::string& name);
|
||||
bool IsSwipeTrackingFromScrollEventsEnabled();
|
||||
#endif
|
||||
bool IsDarkMode();
|
||||
|
||||
@@ -229,6 +229,11 @@ void SystemPreferences::SetUserDefault(const std::string& name,
|
||||
}
|
||||
}
|
||||
|
||||
void SystemPreferences::RemoveUserDefault(const std::string& name) {
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults removeObjectForKey:base::SysUTF8ToNSString(name)];
|
||||
}
|
||||
|
||||
bool SystemPreferences::IsDarkMode() {
|
||||
NSString* mode = [[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:@"AppleInterfaceStyle"];
|
||||
|
||||
@@ -86,8 +86,10 @@ mate::WrappableBase* Tray::New(mate::Handle<NativeImage> image,
|
||||
return new Tray(args->isolate(), args->GetThis(), image);
|
||||
}
|
||||
|
||||
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
EmitWithFlags("click", modifiers, bounds);
|
||||
void Tray::OnClicked(const gfx::Rect& bounds,
|
||||
const gfx::Point& location,
|
||||
int modifiers) {
|
||||
EmitWithFlags("click", modifiers, bounds, location);
|
||||
}
|
||||
|
||||
void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
@@ -130,6 +132,10 @@ void Tray::OnMouseExited(const gfx::Point& location, int modifiers) {
|
||||
EmitWithFlags("mouse-leave", modifiers, location);
|
||||
}
|
||||
|
||||
void Tray::OnMouseMoved(const gfx::Point& location, int modifiers) {
|
||||
EmitWithFlags("mouse-move", modifiers, location);
|
||||
}
|
||||
|
||||
void Tray::OnDragEntered() {
|
||||
Emit("drag-enter");
|
||||
}
|
||||
|
||||
@@ -47,7 +47,9 @@ class Tray : public mate::TrackableObject<Tray>,
|
||||
~Tray() override;
|
||||
|
||||
// TrayIconObserver:
|
||||
void OnClicked(const gfx::Rect& bounds, int modifiers) override;
|
||||
void OnClicked(const gfx::Rect& bounds,
|
||||
const gfx::Point& location,
|
||||
int modifiers) override;
|
||||
void OnDoubleClicked(const gfx::Rect& bounds, int modifiers) override;
|
||||
void OnRightClicked(const gfx::Rect& bounds, int modifiers) override;
|
||||
void OnBalloonShow() override;
|
||||
@@ -61,6 +63,7 @@ class Tray : public mate::TrackableObject<Tray>,
|
||||
void OnDragEnded() override;
|
||||
void OnMouseEntered(const gfx::Point& location, int modifiers) override;
|
||||
void OnMouseExited(const gfx::Point& location, int modifiers) override;
|
||||
void OnMouseMoved(const gfx::Point& location, int modifiers) override;
|
||||
|
||||
void SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
|
||||
void SetPressedImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "content/browser/renderer_host/render_widget_host_view_base.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
#include "content/common/view_messages.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/favicon_status.h"
|
||||
#include "content/public/browser/native_web_keyboard_event.h"
|
||||
#include "content/public/browser/navigation_details.h"
|
||||
@@ -81,6 +82,7 @@
|
||||
#include "third_party/WebKit/public/web/WebFindOptions.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/events/base_event_utils.h"
|
||||
#include "ui/latency/latency_info.h"
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
#include "ui/aura/window.h"
|
||||
@@ -303,6 +305,10 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
|
||||
request_id_(0),
|
||||
background_throttling_(true),
|
||||
enable_devtools_(true) {
|
||||
// WebContents may need to emit events when it is garbage collected, so it
|
||||
// has to be deleted in the first gc callback.
|
||||
MarkHighMemoryUsage();
|
||||
|
||||
// Read options.
|
||||
options.Get("backgroundThrottling", &background_throttling_);
|
||||
|
||||
@@ -586,16 +592,18 @@ void WebContents::HandleKeyboardEvent(
|
||||
}
|
||||
}
|
||||
|
||||
bool WebContents::PreHandleKeyboardEvent(
|
||||
content::KeyboardEventProcessingResult WebContents::PreHandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event,
|
||||
bool* is_keyboard_shortcut) {
|
||||
if (event.type() == blink::WebInputEvent::Type::RawKeyDown ||
|
||||
event.type() == blink::WebInputEvent::Type::KeyUp) {
|
||||
return Emit("before-input-event", event);
|
||||
} else {
|
||||
return false;
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
if (event.GetType() == blink::WebInputEvent::Type::kRawKeyDown ||
|
||||
event.GetType() == blink::WebInputEvent::Type::kKeyUp) {
|
||||
bool prevent_default = Emit("before-input-event", event);
|
||||
if (prevent_default) {
|
||||
return content::KeyboardEventProcessingResult::HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
return content::KeyboardEventProcessingResult::NOT_HANDLED;
|
||||
}
|
||||
|
||||
void WebContents::EnterFullscreenModeForTab(content::WebContents* source,
|
||||
@@ -753,7 +761,11 @@ void WebContents::MediaStoppedPlaying(const MediaPlayerInfo& video_type,
|
||||
}
|
||||
|
||||
void WebContents::DidChangeThemeColor(SkColor theme_color) {
|
||||
Emit("did-change-theme-color", atom::ToRGBHex(theme_color));
|
||||
if (theme_color != SK_ColorTRANSPARENT) {
|
||||
Emit("did-change-theme-color", atom::ToRGBHex(theme_color));
|
||||
} else {
|
||||
Emit("did-change-theme-color", nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void WebContents::DocumentLoadedInFrame(
|
||||
@@ -818,7 +830,7 @@ void WebContents::DidFinishNavigation(
|
||||
bool is_main_frame = navigation_handle->IsInMainFrame();
|
||||
if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) {
|
||||
auto url = navigation_handle->GetURL();
|
||||
bool is_in_page = navigation_handle->IsSamePage();
|
||||
bool is_in_page = navigation_handle->IsSameDocument();
|
||||
if (is_main_frame && !is_in_page) {
|
||||
Emit("did-navigate", url);
|
||||
} else if (is_in_page) {
|
||||
@@ -1002,7 +1014,7 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
|
||||
GURL http_referrer;
|
||||
if (options.Get("httpReferrer", &http_referrer))
|
||||
params.referrer = content::Referrer(http_referrer.GetAsReferrer(),
|
||||
blink::WebReferrerPolicyDefault);
|
||||
blink::kWebReferrerPolicyDefault);
|
||||
|
||||
std::string user_agent;
|
||||
if (options.Get("userAgent", &user_agent))
|
||||
@@ -1240,9 +1252,22 @@ void WebContents::HasServiceWorker(
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
context->CheckHasServiceWorker(web_contents()->GetLastCommittedURL(),
|
||||
GURL::EmptyGURL(),
|
||||
callback);
|
||||
struct WrappedCallback {
|
||||
base::Callback<void(bool)> callback_;
|
||||
explicit WrappedCallback(const base::Callback<void(bool)>& callback)
|
||||
: callback_(callback) {}
|
||||
void Run(content::ServiceWorkerCapability capability) {
|
||||
callback_.Run(capability !=
|
||||
content::ServiceWorkerCapability::NO_SERVICE_WORKER);
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
auto wrapped_callback = new WrappedCallback(callback);
|
||||
|
||||
context->CheckHasServiceWorker(
|
||||
web_contents()->GetLastCommittedURL(), GURL::EmptyGURL(),
|
||||
base::Bind(&WrappedCallback::Run, base::Unretained(wrapped_callback)));
|
||||
}
|
||||
|
||||
void WebContents::UnregisterServiceWorker(
|
||||
@@ -1269,13 +1294,21 @@ bool WebContents::IsAudioMuted() {
|
||||
|
||||
void WebContents::Print(mate::Arguments* args) {
|
||||
PrintSettings settings = { false, false, base::string16() };
|
||||
if (args->Length() == 1 && !args->GetNext(&settings)) {
|
||||
if (args->Length() >= 1 && !args->GetNext(&settings)) {
|
||||
args->ThrowError();
|
||||
return;
|
||||
}
|
||||
|
||||
printing::PrintViewManagerBasic::FromWebContents(web_contents())->
|
||||
PrintNow(web_contents()->GetMainFrame(),
|
||||
auto print_view_manager_basic_ptr =
|
||||
printing::PrintViewManagerBasic::FromWebContents(web_contents());
|
||||
if (args->Length() == 2) {
|
||||
base::Callback<void(bool)> callback;
|
||||
if (!args->GetNext(&callback)) {
|
||||
args->ThrowError();
|
||||
return;
|
||||
}
|
||||
print_view_manager_basic_ptr->SetCallback(callback);
|
||||
}
|
||||
print_view_manager_basic_ptr->PrintNow(web_contents()->GetMainFrame(),
|
||||
settings.silent,
|
||||
settings.print_background,
|
||||
settings.device_name);
|
||||
@@ -1426,22 +1459,22 @@ void WebContents::SendInputEvent(v8::Isolate* isolate,
|
||||
return;
|
||||
|
||||
int type = mate::GetWebInputEventType(isolate, input_event);
|
||||
if (blink::WebInputEvent::isMouseEventType(type)) {
|
||||
if (blink::WebInputEvent::IsMouseEventType(type)) {
|
||||
blink::WebMouseEvent mouse_event;
|
||||
if (mate::ConvertFromV8(isolate, input_event, &mouse_event)) {
|
||||
view->ProcessMouseEvent(mouse_event, ui::LatencyInfo());
|
||||
return;
|
||||
}
|
||||
} else if (blink::WebInputEvent::isKeyboardEventType(type)) {
|
||||
} else if (blink::WebInputEvent::IsKeyboardEventType(type)) {
|
||||
content::NativeWebKeyboardEvent keyboard_event(
|
||||
blink::WebKeyboardEvent::RawKeyDown,
|
||||
blink::WebInputEvent::NoModifiers,
|
||||
blink::WebKeyboardEvent::kRawKeyDown,
|
||||
blink::WebInputEvent::kNoModifiers,
|
||||
ui::EventTimeForNow());
|
||||
if (mate::ConvertFromV8(isolate, input_event, &keyboard_event)) {
|
||||
view->ProcessKeyboardEvent(keyboard_event);
|
||||
return;
|
||||
}
|
||||
} else if (type == blink::WebInputEvent::MouseWheel) {
|
||||
} else if (type == blink::WebInputEvent::kMouseWheel) {
|
||||
blink::WebMouseWheelEvent mouse_wheel_event;
|
||||
if (mate::ConvertFromV8(isolate, input_event, &mouse_wheel_event)) {
|
||||
view->ProcessMouseWheelEvent(mouse_wheel_event, ui::LatencyInfo());
|
||||
@@ -1541,7 +1574,7 @@ void WebContents::CapturePage(mate::Arguments* args) {
|
||||
gfx::Size bitmap_size = view_size;
|
||||
const gfx::NativeView native_view = view->GetNativeView();
|
||||
const float scale =
|
||||
display::Screen::GetScreen()->GetDisplayNearestWindow(native_view)
|
||||
display::Screen::GetScreen()->GetDisplayNearestView(native_view)
|
||||
.device_scale_factor();
|
||||
if (scale > 1.0f)
|
||||
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
|
||||
@@ -1553,7 +1586,7 @@ void WebContents::CapturePage(mate::Arguments* args) {
|
||||
}
|
||||
|
||||
void WebContents::OnCursorChange(const content::WebCursor& cursor) {
|
||||
content::WebCursor::CursorInfo info;
|
||||
content::CursorInfo info;
|
||||
cursor.GetCursorInfo(&info);
|
||||
|
||||
if (cursor.IsCustom()) {
|
||||
@@ -1758,6 +1791,16 @@ void WebContents::SetEmbedder(const WebContents* embedder) {
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebContents::GetNativeView() const {
|
||||
gfx::NativeView ptr = web_contents()->GetNativeView();
|
||||
auto buffer = node::Buffer::Copy(
|
||||
isolate(), reinterpret_cast<char*>(&ptr), sizeof(gfx::NativeView));
|
||||
if (buffer.IsEmpty())
|
||||
return v8::Null(isolate());
|
||||
else
|
||||
return buffer.ToLocalChecked();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebContents::DevToolsWebContents(v8::Isolate* isolate) {
|
||||
if (devtools_web_contents_.IsEmpty())
|
||||
return v8::Null(isolate);
|
||||
@@ -1773,6 +1816,12 @@ v8::Local<v8::Value> WebContents::Debugger(v8::Isolate* isolate) {
|
||||
return v8::Local<v8::Value>::New(isolate, debugger_);
|
||||
}
|
||||
|
||||
void WebContents::GrantOriginAccess(const GURL& url) {
|
||||
content::ChildProcessSecurityPolicy::GetInstance()->GrantOrigin(
|
||||
web_contents()->GetMainFrame()->GetProcess()->GetID(),
|
||||
url::Origin(url));
|
||||
}
|
||||
|
||||
// static
|
||||
void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
@@ -1863,10 +1912,12 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("copyImageAt", &WebContents::CopyImageAt)
|
||||
.SetMethod("capturePage", &WebContents::CapturePage)
|
||||
.SetMethod("setEmbedder", &WebContents::SetEmbedder)
|
||||
.SetMethod("getNativeView", &WebContents::GetNativeView)
|
||||
.SetMethod("setWebRTCIPHandlingPolicy",
|
||||
&WebContents::SetWebRTCIPHandlingPolicy)
|
||||
.SetMethod("getWebRTCIPHandlingPolicy",
|
||||
&WebContents::GetWebRTCIPHandlingPolicy)
|
||||
.SetMethod("_grantOriginAccess", &WebContents::GrantOriginAccess)
|
||||
.SetProperty("id", &WebContents::ID)
|
||||
.SetProperty("session", &WebContents::Session)
|
||||
.SetProperty("hostWebContents", &WebContents::HostWebContents)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
#include "atom/browser/ui/autofill_popup.h"
|
||||
#include "content/common/cursors/webcursor.h"
|
||||
#include "content/public/browser/keyboard_event_processing_result.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "content/public/common/favicon_url.h"
|
||||
#include "native_mate/handle.h"
|
||||
@@ -115,7 +116,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void DisableDeviceEmulation();
|
||||
void InspectElement(int x, int y);
|
||||
void InspectServiceWorker();
|
||||
void HasServiceWorker(const base::Callback<void(bool)>&);
|
||||
void HasServiceWorker(
|
||||
const base::Callback<void(bool)>&);
|
||||
void UnregisterServiceWorker(const base::Callback<void(bool)>&);
|
||||
void SetIgnoreMenuShortcuts(bool ignore);
|
||||
void SetAudioMuted(bool muted);
|
||||
@@ -123,6 +125,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void Print(mate::Arguments* args);
|
||||
std::vector<printing::PrinterBasicInfo> GetPrinterList();
|
||||
void SetEmbedder(const WebContents* embedder);
|
||||
v8::Local<v8::Value> GetNativeView() const;
|
||||
|
||||
// Print current page as PDF.
|
||||
void PrintToPDF(const base::DictionaryValue& setting,
|
||||
@@ -214,6 +217,10 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// Returns the owner window.
|
||||
v8::Local<v8::Value> GetOwnerBrowserWindow();
|
||||
|
||||
// Grants the child process the capability to access URLs with the origin of
|
||||
// the specified URL.
|
||||
void GrantOriginAccess(const GURL& url);
|
||||
|
||||
// Properties.
|
||||
int32_t ID() const;
|
||||
v8::Local<v8::Value> Session(v8::Isolate* isolate);
|
||||
@@ -268,9 +275,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
bool PreHandleKeyboardEvent(content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event,
|
||||
bool* is_keyboard_shortcut) override;
|
||||
content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
void EnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin) override;
|
||||
void ExitFullscreenModeForTab(content::WebContents* source) override;
|
||||
|
||||
@@ -603,6 +603,14 @@ void Window::SetSkipTaskbar(bool skip) {
|
||||
window_->SetSkipTaskbar(skip);
|
||||
}
|
||||
|
||||
void Window::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||
window_->SetSimpleFullScreen(simple_fullscreen);
|
||||
}
|
||||
|
||||
bool Window::IsSimpleFullScreen() {
|
||||
return window_->IsSimpleFullScreen();
|
||||
}
|
||||
|
||||
void Window::SetKiosk(bool kiosk) {
|
||||
window_->SetKiosk(kiosk);
|
||||
}
|
||||
@@ -623,6 +631,14 @@ bool Window::HasShadow() {
|
||||
return window_->HasShadow();
|
||||
}
|
||||
|
||||
void Window::SetOpacity(const double opacity) {
|
||||
window_->SetOpacity(opacity);
|
||||
}
|
||||
|
||||
double Window::GetOpacity() {
|
||||
return window_->GetOpacity();
|
||||
}
|
||||
|
||||
void Window::FocusOnWebView() {
|
||||
window_->FocusOnWebView();
|
||||
}
|
||||
@@ -651,8 +667,11 @@ bool Window::IsDocumentEdited() {
|
||||
return window_->IsDocumentEdited();
|
||||
}
|
||||
|
||||
void Window::SetIgnoreMouseEvents(bool ignore) {
|
||||
return window_->SetIgnoreMouseEvents(ignore);
|
||||
void Window::SetIgnoreMouseEvents(bool ignore, mate::Arguments* args) {
|
||||
mate::Dictionary options;
|
||||
bool forward = false;
|
||||
args->GetNext(&options) && options.Get("forward", &forward);
|
||||
return window_->SetIgnoreMouseEvents(ignore, forward);
|
||||
}
|
||||
|
||||
void Window::SetContentProtection(bool enable) {
|
||||
@@ -907,6 +926,30 @@ void Window::SetAutoHideCursor(bool auto_hide) {
|
||||
window_->SetAutoHideCursor(auto_hide);
|
||||
}
|
||||
|
||||
void Window::SelectPreviousTab() {
|
||||
window_->SelectPreviousTab();
|
||||
}
|
||||
|
||||
void Window::SelectNextTab() {
|
||||
window_->SelectNextTab();
|
||||
}
|
||||
|
||||
void Window::MergeAllWindows() {
|
||||
window_->MergeAllWindows();
|
||||
}
|
||||
|
||||
void Window::MoveTabToNewWindow() {
|
||||
window_->MoveTabToNewWindow();
|
||||
}
|
||||
|
||||
void Window::ToggleTabBar() {
|
||||
window_->ToggleTabBar();
|
||||
}
|
||||
|
||||
void Window::AddTabbedWindow(NativeWindow* window) {
|
||||
window_->AddTabbedWindow(window);
|
||||
}
|
||||
|
||||
void Window::SetVibrancy(mate::Arguments* args) {
|
||||
std::string type;
|
||||
|
||||
@@ -1018,11 +1061,15 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getTitle", &Window::GetTitle)
|
||||
.SetMethod("flashFrame", &Window::FlashFrame)
|
||||
.SetMethod("setSkipTaskbar", &Window::SetSkipTaskbar)
|
||||
.SetMethod("setSimpleFullScreen", &Window::SetSimpleFullScreen)
|
||||
.SetMethod("isSimpleFullScreen", &Window::IsSimpleFullScreen)
|
||||
.SetMethod("setKiosk", &Window::SetKiosk)
|
||||
.SetMethod("isKiosk", &Window::IsKiosk)
|
||||
.SetMethod("setBackgroundColor", &Window::SetBackgroundColor)
|
||||
.SetMethod("setHasShadow", &Window::SetHasShadow)
|
||||
.SetMethod("hasShadow", &Window::HasShadow)
|
||||
.SetMethod("setOpacity", &Window::SetOpacity)
|
||||
.SetMethod("getOpacity", &Window::GetOpacity)
|
||||
.SetMethod("setRepresentedFilename", &Window::SetRepresentedFilename)
|
||||
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
|
||||
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
||||
@@ -1047,6 +1094,12 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
&Window::IsVisibleOnAllWorkspaces)
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("setAutoHideCursor", &Window::SetAutoHideCursor)
|
||||
.SetMethod("mergeAllWindows", &Window::MergeAllWindows)
|
||||
.SetMethod("selectPreviousTab", &Window::SelectPreviousTab)
|
||||
.SetMethod("selectNextTab", &Window::SelectNextTab)
|
||||
.SetMethod("moveTabToNewWindow", &Window::MoveTabToNewWindow)
|
||||
.SetMethod("toggleTabBar", &Window::ToggleTabBar)
|
||||
.SetMethod("addTabbedWindow", &Window::AddTabbedWindow)
|
||||
#endif
|
||||
.SetMethod("setVibrancy", &Window::SetVibrancy)
|
||||
.SetMethod("_setTouchBarItems", &Window::SetTouchBar)
|
||||
|
||||
@@ -154,11 +154,15 @@ class Window : public mate::TrackableObject<Window>,
|
||||
std::string GetTitle();
|
||||
void FlashFrame(bool flash);
|
||||
void SetSkipTaskbar(bool skip);
|
||||
void SetSimpleFullScreen(bool simple_fullscreen);
|
||||
bool IsSimpleFullScreen();
|
||||
void SetKiosk(bool kiosk);
|
||||
bool IsKiosk();
|
||||
void SetBackgroundColor(const std::string& color_name);
|
||||
void SetHasShadow(bool has_shadow);
|
||||
bool HasShadow();
|
||||
void SetOpacity(const double opacity);
|
||||
double GetOpacity();
|
||||
void FocusOnWebView();
|
||||
void BlurWebView();
|
||||
bool IsWebViewFocused();
|
||||
@@ -166,7 +170,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||
std::string GetRepresentedFilename();
|
||||
void SetDocumentEdited(bool edited);
|
||||
bool IsDocumentEdited();
|
||||
void SetIgnoreMouseEvents(bool ignore);
|
||||
void SetIgnoreMouseEvents(bool ignore, mate::Arguments* args);
|
||||
void SetContentProtection(bool enable);
|
||||
void SetFocusable(bool focusable);
|
||||
void SetProgressBar(double progress, mate::Arguments* args);
|
||||
@@ -212,6 +216,13 @@ class Window : public mate::TrackableObject<Window>,
|
||||
|
||||
void SetAutoHideCursor(bool auto_hide);
|
||||
|
||||
void SelectPreviousTab();
|
||||
void SelectNextTab();
|
||||
void MergeAllWindows();
|
||||
void MoveTabToNewWindow();
|
||||
void ToggleTabBar();
|
||||
void AddTabbedWindow(NativeWindow* window);
|
||||
|
||||
void SetVibrancy(mate::Arguments* args);
|
||||
void SetTouchBar(const std::vector<mate::PersistentDictionary>& items);
|
||||
void RefreshTouchBarItem(const std::string& item_id);
|
||||
|
||||
@@ -45,9 +45,9 @@ bool FrameSubscriber::ShouldCaptureFrame(
|
||||
|
||||
gfx::Size view_size = rect.size();
|
||||
gfx::Size bitmap_size = view_size;
|
||||
const gfx::NativeView native_view = view_->GetNativeView();
|
||||
gfx::NativeView native_view = view_->GetNativeView();
|
||||
const float scale =
|
||||
display::Screen::GetScreen()->GetDisplayNearestWindow(native_view)
|
||||
display::Screen::GetScreen()->GetDisplayNearestView(native_view)
|
||||
.device_scale_factor();
|
||||
if (scale > 1.0f)
|
||||
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
|
||||
@@ -78,20 +78,32 @@ void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback,
|
||||
v8::Locker locker(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
|
||||
size_t rgb_arr_size = bitmap.width() * bitmap.height() *
|
||||
bitmap.bytesPerPixel();
|
||||
v8::MaybeLocal<v8::Object> buffer = node::Buffer::New(isolate_, rgb_arr_size);
|
||||
size_t rgb_row_size = bitmap.width() * bitmap.bytesPerPixel();
|
||||
|
||||
v8::MaybeLocal<v8::Object> buffer =
|
||||
node::Buffer::New(isolate_, rgb_row_size * bitmap.height());
|
||||
|
||||
if (buffer.IsEmpty())
|
||||
return;
|
||||
|
||||
bitmap.copyPixelsTo(
|
||||
reinterpret_cast<uint8_t*>(node::Buffer::Data(buffer.ToLocalChecked())),
|
||||
rgb_arr_size);
|
||||
auto local_buffer = buffer.ToLocalChecked();
|
||||
|
||||
{
|
||||
SkAutoLockPixels lock(bitmap);
|
||||
auto source = static_cast<const unsigned char*>(bitmap.getPixels());
|
||||
auto target = node::Buffer::Data(local_buffer);
|
||||
|
||||
for (int y = 0; y < bitmap.height(); ++y) {
|
||||
memcpy(target, source, rgb_row_size);
|
||||
source += bitmap.rowBytes();
|
||||
target += rgb_row_size;
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> damage =
|
||||
mate::Converter<gfx::Rect>::ToV8(isolate_, damage_rect);
|
||||
|
||||
callback_.Run(buffer.ToLocalChecked(), damage);
|
||||
callback_.Run(local_buffer, damage);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/supports_user_data.h"
|
||||
|
||||
namespace mate {
|
||||
@@ -46,16 +47,19 @@ void TrackableObjectBase::Destroy() {
|
||||
}
|
||||
|
||||
void TrackableObjectBase::AttachAsUserData(base::SupportsUserData* wrapped) {
|
||||
wrapped->SetUserData(kTrackedObjectKey, new IDUserData(weak_map_id_));
|
||||
wrapped->SetUserData(kTrackedObjectKey,
|
||||
base::MakeUnique<IDUserData>(weak_map_id_));
|
||||
}
|
||||
|
||||
// static
|
||||
int32_t TrackableObjectBase::GetIDFromWrappedClass(base::SupportsUserData* w) {
|
||||
auto id = static_cast<IDUserData*>(w->GetUserData(kTrackedObjectKey));
|
||||
if (id)
|
||||
return *id;
|
||||
else
|
||||
return 0;
|
||||
int32_t TrackableObjectBase::GetIDFromWrappedClass(
|
||||
base::SupportsUserData* wrapped) {
|
||||
if (wrapped) {
|
||||
auto id = static_cast<IDUserData*>(wrapped->GetUserData(kTrackedObjectKey));
|
||||
if (id)
|
||||
return *id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -30,15 +30,15 @@ class TrackableObjectBase {
|
||||
// Wrap TrackableObject into a class that SupportsUserData.
|
||||
void AttachAsUserData(base::SupportsUserData* wrapped);
|
||||
|
||||
// Get the weak_map_id from SupportsUserData.
|
||||
static int32_t GetIDFromWrappedClass(base::SupportsUserData* wrapped);
|
||||
|
||||
protected:
|
||||
virtual ~TrackableObjectBase();
|
||||
|
||||
// Returns a closure that can destroy the native class.
|
||||
base::Closure GetDestroyClosure();
|
||||
|
||||
// Get the weak_map_id from SupportsUserData.
|
||||
static int32_t GetIDFromWrappedClass(base::SupportsUserData* wrapped);
|
||||
|
||||
// Register a callback that should be destroyed before JavaScript environment
|
||||
// gets destroyed.
|
||||
static base::Closure RegisterDestructionCallback(const base::Closure& c);
|
||||
|
||||
@@ -115,7 +115,10 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||
// If user cancels the file save dialog, run the callback with empty FilePath.
|
||||
callback.Run(path,
|
||||
content::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path);
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path,
|
||||
path.empty() ?
|
||||
content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED :
|
||||
content::DOWNLOAD_INTERRUPT_REASON_NONE);
|
||||
}
|
||||
|
||||
void AtomDownloadManagerDelegate::Shutdown() {
|
||||
@@ -132,7 +135,8 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget(
|
||||
callback.Run(download->GetForcedFilePath(),
|
||||
content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
download->GetForcedFilePath());
|
||||
download->GetForcedFilePath(),
|
||||
content::DOWNLOAD_INTERRUPT_REASON_NONE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -143,7 +147,7 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget(
|
||||
callback.Run(save_path,
|
||||
content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
save_path);
|
||||
save_path, content::DOWNLOAD_INTERRUPT_REASON_NONE);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,27 +11,28 @@ namespace atom {
|
||||
void BridgeTaskRunner::MessageLoopIsReady() {
|
||||
auto message_loop = base::MessageLoop::current();
|
||||
CHECK(message_loop);
|
||||
for (const TaskPair& task : tasks_) {
|
||||
for (TaskPair& task : tasks_) {
|
||||
message_loop->task_runner()->PostDelayedTask(
|
||||
base::get<0>(task), base::get<1>(task), base::get<2>(task));
|
||||
std::get<0>(task), std::move(std::get<1>(task)), std::get<2>(task));
|
||||
}
|
||||
for (const TaskPair& task : non_nestable_tasks_) {
|
||||
for (TaskPair& task : non_nestable_tasks_) {
|
||||
message_loop->task_runner()->PostNonNestableDelayedTask(
|
||||
base::get<0>(task), base::get<1>(task), base::get<2>(task));
|
||||
std::get<0>(task), std::move(std::get<1>(task)), std::get<2>(task));
|
||||
}
|
||||
}
|
||||
|
||||
bool BridgeTaskRunner::PostDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::OnceClosure task,
|
||||
base::TimeDelta delay) {
|
||||
auto message_loop = base::MessageLoop::current();
|
||||
if (!message_loop) {
|
||||
tasks_.push_back(std::make_tuple(from_here, task, delay));
|
||||
tasks_.push_back(std::make_tuple(from_here, std::move(task), delay));
|
||||
return true;
|
||||
}
|
||||
|
||||
return message_loop->task_runner()->PostDelayedTask(from_here, task, delay);
|
||||
return message_loop->task_runner()->PostDelayedTask(
|
||||
from_here, std::move(task), delay);
|
||||
}
|
||||
|
||||
bool BridgeTaskRunner::RunsTasksOnCurrentThread() const {
|
||||
@@ -44,16 +45,17 @@ bool BridgeTaskRunner::RunsTasksOnCurrentThread() const {
|
||||
|
||||
bool BridgeTaskRunner::PostNonNestableDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::OnceClosure task,
|
||||
base::TimeDelta delay) {
|
||||
auto message_loop = base::MessageLoop::current();
|
||||
if (!message_loop) {
|
||||
non_nestable_tasks_.push_back(std::make_tuple(from_here, task, delay));
|
||||
non_nestable_tasks_.push_back(std::make_tuple(
|
||||
from_here, std::move(task), delay));
|
||||
return true;
|
||||
}
|
||||
|
||||
return message_loop->task_runner()->PostNonNestableDelayedTask(
|
||||
from_here, task, delay);
|
||||
from_here, std::move(task), delay);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -25,17 +25,17 @@ class BridgeTaskRunner : public base::SingleThreadTaskRunner {
|
||||
|
||||
// base::SingleThreadTaskRunner:
|
||||
bool PostDelayedTask(const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::OnceClosure task,
|
||||
base::TimeDelta delay) override;
|
||||
bool RunsTasksOnCurrentThread() const override;
|
||||
bool PostNonNestableDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
const base::Closure& task,
|
||||
base::OnceClosure task,
|
||||
base::TimeDelta delay) override;
|
||||
|
||||
private:
|
||||
using TaskPair = std::tuple<
|
||||
tracked_objects::Location, base::Closure, base::TimeDelta>;
|
||||
tracked_objects::Location, base::OnceClosure, base::TimeDelta>;
|
||||
std::vector<TaskPair> tasks_;
|
||||
std::vector<TaskPair> non_nestable_tasks_;
|
||||
|
||||
|
||||
@@ -119,10 +119,32 @@ class Browser : public WindowListObserver {
|
||||
// Returns the type name of the current user activity.
|
||||
std::string GetCurrentActivityType();
|
||||
|
||||
// Invalidates the current user activity.
|
||||
void InvalidateCurrentActivity();
|
||||
|
||||
// Updates the current user activity
|
||||
void UpdateCurrentActivity(const std::string& type,
|
||||
const base::DictionaryValue& user_info);
|
||||
|
||||
// Indicates that an user activity is about to be resumed.
|
||||
bool WillContinueUserActivity(const std::string& type);
|
||||
|
||||
// Indicates a failure to resume a Handoff activity.
|
||||
void DidFailToContinueUserActivity(const std::string& type,
|
||||
const std::string& error);
|
||||
|
||||
// Resumes an activity via hand-off.
|
||||
bool ContinueUserActivity(const std::string& type,
|
||||
const base::DictionaryValue& user_info);
|
||||
|
||||
// Indicates that an activity was continued on another device.
|
||||
void UserActivityWasContinued(const std::string& type,
|
||||
const base::DictionaryValue& user_info);
|
||||
|
||||
// Gives an oportunity to update the Handoff payload.
|
||||
bool UpdateUserActivityState(const std::string& type,
|
||||
const base::DictionaryValue& user_info);
|
||||
|
||||
// Bounce the dock icon.
|
||||
enum BounceType {
|
||||
BOUNCE_CRITICAL = 0,
|
||||
|
||||
@@ -4,16 +4,62 @@
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/process/launch.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
|
||||
#if defined(USE_X11)
|
||||
#include "chrome/browser/ui/libgtkui/gtk_util.h"
|
||||
#include "chrome/browser/ui/libgtkui/unity_service.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
const char kXdgSettings[] = "xdg-settings";
|
||||
const char kXdgSettingsDefaultSchemeHandler[] = "default-url-scheme-handler";
|
||||
|
||||
bool LaunchXdgUtility(const std::vector<std::string>& argv, int* exit_code) {
|
||||
*exit_code = EXIT_FAILURE;
|
||||
int devnull = open("/dev/null", O_RDONLY);
|
||||
if (devnull < 0) return false;
|
||||
|
||||
base::LaunchOptions options;
|
||||
|
||||
base::FileHandleMappingVector remap;
|
||||
remap.push_back(std::make_pair(devnull, STDIN_FILENO));
|
||||
options.fds_to_remap = &remap;
|
||||
|
||||
base::Process process = base::LaunchProcess(argv, options);
|
||||
close(devnull);
|
||||
|
||||
if (!process.IsValid()) return false;
|
||||
return process.WaitForExit(exit_code);
|
||||
}
|
||||
|
||||
bool SetDefaultWebClient(const std::string& protocol) {
|
||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
||||
|
||||
std::vector<std::string> argv;
|
||||
argv.push_back(kXdgSettings);
|
||||
argv.push_back("set");
|
||||
if (!protocol.empty()) {
|
||||
argv.push_back(kXdgSettingsDefaultSchemeHandler);
|
||||
argv.push_back(protocol);
|
||||
}
|
||||
argv.push_back(libgtkui::GetDesktopName(env.get()));
|
||||
|
||||
int exit_code;
|
||||
bool ran_ok = LaunchXdgUtility(argv, &exit_code);
|
||||
return ran_ok && exit_code == EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void Browser::Focus() {
|
||||
// Focus on the first visible window.
|
||||
for (const auto& window : WindowList::GetWindows()) {
|
||||
@@ -33,18 +79,40 @@ void Browser::ClearRecentDocuments() {
|
||||
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||
}
|
||||
|
||||
bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol,
|
||||
mate::Arguments* args) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Browser::SetAsDefaultProtocolClient(const std::string& protocol,
|
||||
mate::Arguments* args) {
|
||||
return false;
|
||||
return SetDefaultWebClient(protocol);
|
||||
}
|
||||
|
||||
bool Browser::IsDefaultProtocolClient(const std::string& protocol,
|
||||
mate::Arguments* args) {
|
||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
||||
|
||||
if (protocol.empty()) return false;
|
||||
|
||||
std::vector<std::string> argv;
|
||||
argv.push_back(kXdgSettings);
|
||||
argv.push_back("check");
|
||||
argv.push_back(kXdgSettingsDefaultSchemeHandler);
|
||||
argv.push_back(protocol);
|
||||
argv.push_back(libgtkui::GetDesktopName(env.get()));
|
||||
|
||||
std::string reply;
|
||||
int success_code;
|
||||
bool ran_ok = base::GetAppOutputWithExitCode(base::CommandLine(argv),
|
||||
&reply, &success_code);
|
||||
|
||||
if (!ran_ok || success_code != EXIT_SUCCESS) return false;
|
||||
|
||||
// Allow any reply that starts with "yes".
|
||||
return base::StartsWith(reply, "yes", base::CompareCase::SENSITIVE)
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
|
||||
// Todo implement
|
||||
bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol,
|
||||
mate::Arguments* args) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,6 +144,30 @@ std::string Browser::GetCurrentActivityType() {
|
||||
return base::SysNSStringToUTF8(userActivity.activityType);
|
||||
}
|
||||
|
||||
void Browser::InvalidateCurrentActivity() {
|
||||
[[AtomApplication sharedApplication] invalidateCurrentActivity];
|
||||
}
|
||||
|
||||
void Browser::UpdateCurrentActivity(const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
[[AtomApplication sharedApplication]
|
||||
updateCurrentActivity:base::SysUTF8ToNSString(type)
|
||||
withUserInfo:DictionaryValueToNSDictionary(user_info)];
|
||||
}
|
||||
|
||||
bool Browser::WillContinueUserActivity(const std::string& type) {
|
||||
bool prevent_default = false;
|
||||
for (BrowserObserver& observer : observers_)
|
||||
observer.OnWillContinueUserActivity(&prevent_default, type);
|
||||
return prevent_default;
|
||||
}
|
||||
|
||||
void Browser::DidFailToContinueUserActivity(const std::string& type,
|
||||
const std::string& error) {
|
||||
for (BrowserObserver& observer : observers_)
|
||||
observer.OnDidFailToContinueUserActivity(type, error);
|
||||
}
|
||||
|
||||
bool Browser::ContinueUserActivity(const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
bool prevent_default = false;
|
||||
@@ -152,6 +176,20 @@ bool Browser::ContinueUserActivity(const std::string& type,
|
||||
return prevent_default;
|
||||
}
|
||||
|
||||
void Browser::UserActivityWasContinued(const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
for (BrowserObserver& observer : observers_)
|
||||
observer.OnUserActivityWasContinued(type, user_info);
|
||||
}
|
||||
|
||||
bool Browser::UpdateUserActivityState(const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
bool prevent_default = false;
|
||||
for (BrowserObserver& observer : observers_)
|
||||
observer.OnUpdateUserActivityState(&prevent_default, type, user_info);
|
||||
return prevent_default;
|
||||
}
|
||||
|
||||
Browser::LoginItemSettings Browser::GetLoginItemSettings(
|
||||
const LoginItemSettings& options) {
|
||||
LoginItemSettings settings;
|
||||
|
||||
@@ -59,12 +59,28 @@ class BrowserObserver {
|
||||
virtual void OnPreMainMessageLoopRun() {}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// The browser wants to report that an user activity will resume. (macOS only)
|
||||
virtual void OnWillContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type) {}
|
||||
// The browser wants to report an user activity resuming error. (macOS only)
|
||||
virtual void OnDidFailToContinueUserActivity(
|
||||
const std::string& type,
|
||||
const std::string& error) {}
|
||||
// The browser wants to resume a user activity via handoff. (macOS only)
|
||||
virtual void OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {}
|
||||
|
||||
// The browser wants to notify that an user activity was resumed. (macOS only)
|
||||
virtual void OnUserActivityWasContinued(
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {}
|
||||
// The browser wants to update an user activity payload. (macOS only)
|
||||
virtual void OnUpdateUserActivityState(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {}
|
||||
// User clicked the native macOS new tab button. (macOS only)
|
||||
virtual void OnNewWindowForTab() {}
|
||||
#endif
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "atom/browser/web_dialog_helper.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "chrome/browser/printing/print_preview_message_handler.h"
|
||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||
#include "chrome/browser/ssl/security_state_tab_helper.h"
|
||||
@@ -300,7 +301,7 @@ void CommonWebContentsDelegate::DevToolsSaveToFile(
|
||||
settings.title = url;
|
||||
settings.default_path = base::FilePath::FromUTF8Unsafe(url);
|
||||
if (!file_dialog::ShowSaveDialog(settings, &path)) {
|
||||
base::StringValue url_value(url);
|
||||
base::Value url_value(url);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.canceledSaveURL", &url_value, nullptr, nullptr);
|
||||
return;
|
||||
@@ -384,7 +385,7 @@ void CommonWebContentsDelegate::DevToolsAddFileSystem(
|
||||
auto pref_service = GetPrefService(GetDevToolsWebContents());
|
||||
DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths);
|
||||
update.Get()->SetWithoutPathExpansion(
|
||||
path.AsUTF8Unsafe(), base::Value::CreateNullValue());
|
||||
path.AsUTF8Unsafe(), base::MakeUnique<base::Value>());
|
||||
|
||||
web_contents_->CallClientFunction("DevToolsAPI.fileSystemAdded",
|
||||
file_system_value.get(),
|
||||
@@ -404,7 +405,7 @@ void CommonWebContentsDelegate::DevToolsRemoveFileSystem(
|
||||
DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths);
|
||||
update.Get()->RemoveWithoutPathExpansion(path, nullptr);
|
||||
|
||||
base::StringValue file_system_path_value(path);
|
||||
base::Value file_system_path_value(path);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.fileSystemRemoved",
|
||||
&file_system_path_value,
|
||||
nullptr, nullptr);
|
||||
@@ -468,7 +469,7 @@ void CommonWebContentsDelegate::DevToolsSearchInPath(
|
||||
void CommonWebContentsDelegate::OnDevToolsSaveToFile(
|
||||
const std::string& url) {
|
||||
// Notify DevTools.
|
||||
base::StringValue url_value(url);
|
||||
base::Value url_value(url);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.savedURL", &url_value, nullptr, nullptr);
|
||||
}
|
||||
@@ -476,7 +477,7 @@ void CommonWebContentsDelegate::OnDevToolsSaveToFile(
|
||||
void CommonWebContentsDelegate::OnDevToolsAppendToFile(
|
||||
const std::string& url) {
|
||||
// Notify DevTools.
|
||||
base::StringValue url_value(url);
|
||||
base::Value url_value(url);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.appendedToURL", &url_value, nullptr, nullptr);
|
||||
}
|
||||
@@ -486,7 +487,7 @@ void CommonWebContentsDelegate::OnDevToolsIndexingWorkCalculated(
|
||||
const std::string& file_system_path,
|
||||
int total_work) {
|
||||
base::Value request_id_value(request_id);
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
base::Value file_system_path_value(file_system_path);
|
||||
base::Value total_work_value(total_work);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.indexingTotalWorkCalculated",
|
||||
&request_id_value,
|
||||
@@ -499,7 +500,7 @@ void CommonWebContentsDelegate::OnDevToolsIndexingWorked(
|
||||
const std::string& file_system_path,
|
||||
int worked) {
|
||||
base::Value request_id_value(request_id);
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
base::Value file_system_path_value(file_system_path);
|
||||
base::Value worked_value(worked);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.indexingWorked",
|
||||
&request_id_value,
|
||||
@@ -512,7 +513,7 @@ void CommonWebContentsDelegate::OnDevToolsIndexingDone(
|
||||
const std::string& file_system_path) {
|
||||
devtools_indexing_jobs_.erase(request_id);
|
||||
base::Value request_id_value(request_id);
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
base::Value file_system_path_value(file_system_path);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.indexingDone",
|
||||
&request_id_value,
|
||||
&file_system_path_value,
|
||||
@@ -528,7 +529,7 @@ void CommonWebContentsDelegate::OnDevToolsSearchCompleted(
|
||||
file_paths_value.AppendString(file_path);
|
||||
}
|
||||
base::Value request_id_value(request_id);
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
base::Value file_system_path_value(file_system_path);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.searchCompleted",
|
||||
&request_id_value,
|
||||
&file_system_path_value,
|
||||
|
||||
@@ -20,11 +20,11 @@ void CommonWebContentsDelegate::HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
if (event.skip_in_browser ||
|
||||
event.type() == content::NativeWebKeyboardEvent::Char)
|
||||
event.GetType() == content::NativeWebKeyboardEvent::kChar)
|
||||
return;
|
||||
|
||||
// Escape exits tabbed fullscreen mode.
|
||||
if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen())
|
||||
if (event.windows_key_code == ui::VKEY_ESCAPE && is_html_fullscreen())
|
||||
ExitFullscreenModeForTab(source);
|
||||
|
||||
if (!ignore_menu_shortcuts_) {
|
||||
|
||||
@@ -19,7 +19,7 @@ void CommonWebContentsDelegate::HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
// Escape exits tabbed fullscreen mode.
|
||||
if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen())
|
||||
if (event.windows_key_code == ui::VKEY_ESCAPE && is_html_fullscreen())
|
||||
ExitFullscreenModeForTab(source);
|
||||
|
||||
// Let the NativeWindow handle other parts.
|
||||
|
||||
@@ -33,7 +33,7 @@ class BluetoothChooser : public content::BluetoothChooser {
|
||||
bool is_gatt_connected,
|
||||
bool is_paired,
|
||||
int signal_strength_level) override;
|
||||
void RemoveDevice(const std::string& device_id) override;
|
||||
void RemoveDevice(const std::string& device_id);
|
||||
|
||||
private:
|
||||
std::vector<DeviceInfo> device_list_;
|
||||
|
||||
@@ -6,10 +6,13 @@
|
||||
#import "base/mac/scoped_nsobject.h"
|
||||
|
||||
@interface AtomApplication : NSApplication<CrAppProtocol,
|
||||
CrAppControlProtocol> {
|
||||
CrAppControlProtocol,
|
||||
NSUserActivityDelegate> {
|
||||
@private
|
||||
BOOL handlingSendEvent_;
|
||||
base::scoped_nsobject<NSUserActivity> currentActivity_;
|
||||
NSCondition* handoffLock_;
|
||||
BOOL updateReceived_;
|
||||
}
|
||||
|
||||
+ (AtomApplication*)sharedApplication;
|
||||
@@ -24,5 +27,8 @@
|
||||
- (void)setCurrentActivity:(NSString*)type
|
||||
withUserInfo:(NSDictionary*)userInfo
|
||||
withWebpageURL:(NSURL*)webpageURL;
|
||||
- (void)invalidateCurrentActivity;
|
||||
- (void)updateCurrentActivity:(NSString*)type
|
||||
withUserInfo:(NSDictionary*)userInfo;
|
||||
|
||||
@end
|
||||
|
||||
@@ -4,11 +4,23 @@
|
||||
|
||||
#import "atom/browser/mac/atom_application.h"
|
||||
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "base/auto_reset.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "content/public/browser/browser_accessibility_state.h"
|
||||
|
||||
namespace {
|
||||
|
||||
inline void dispatch_sync_main(dispatch_block_t block) {
|
||||
if ([NSThread isMainThread])
|
||||
block();
|
||||
else
|
||||
dispatch_sync(dispatch_get_main_queue(), block);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@implementation AtomApplication
|
||||
|
||||
+ (AtomApplication*)sharedApplication {
|
||||
@@ -35,19 +47,78 @@
|
||||
[[NSUserActivity alloc] initWithActivityType:type]);
|
||||
[currentActivity_ setUserInfo:userInfo];
|
||||
[currentActivity_ setWebpageURL:webpageURL];
|
||||
[currentActivity_ setDelegate:self];
|
||||
[currentActivity_ becomeCurrent];
|
||||
[currentActivity_ setNeedsSave:YES];
|
||||
}
|
||||
|
||||
- (NSUserActivity*)getCurrentActivity {
|
||||
return currentActivity_.get();
|
||||
}
|
||||
|
||||
- (void)invalidateCurrentActivity {
|
||||
if (currentActivity_) {
|
||||
[currentActivity_ invalidate];
|
||||
currentActivity_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateCurrentActivity:(NSString*)type
|
||||
withUserInfo:(NSDictionary*)userInfo {
|
||||
if (currentActivity_) {
|
||||
[currentActivity_ addUserInfoEntriesFromDictionary:userInfo];
|
||||
}
|
||||
|
||||
[handoffLock_ lock];
|
||||
updateReceived_ = YES;
|
||||
[handoffLock_ signal];
|
||||
[handoffLock_ unlock];
|
||||
}
|
||||
|
||||
- (void)userActivityWillSave:(NSUserActivity *)userActivity {
|
||||
__block BOOL shouldWait = NO;
|
||||
dispatch_sync_main(^{
|
||||
std::string activity_type(base::SysNSStringToUTF8(userActivity.activityType));
|
||||
std::unique_ptr<base::DictionaryValue> user_info =
|
||||
atom::NSDictionaryToDictionaryValue(userActivity.userInfo);
|
||||
|
||||
atom::Browser* browser = atom::Browser::Get();
|
||||
shouldWait = browser->UpdateUserActivityState(activity_type, *user_info) ? YES : NO;
|
||||
});
|
||||
|
||||
if (shouldWait) {
|
||||
[handoffLock_ lock];
|
||||
updateReceived_ = NO;
|
||||
while (!updateReceived_) {
|
||||
BOOL isSignaled = [handoffLock_ waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
|
||||
if (!isSignaled) break;
|
||||
}
|
||||
[handoffLock_ unlock];
|
||||
}
|
||||
|
||||
[userActivity setNeedsSave:YES];
|
||||
}
|
||||
|
||||
- (void)userActivityWasContinued:(NSUserActivity *)userActivity {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
std::string activity_type(base::SysNSStringToUTF8(userActivity.activityType));
|
||||
std::unique_ptr<base::DictionaryValue> user_info =
|
||||
atom::NSDictionaryToDictionaryValue(userActivity.userInfo);
|
||||
|
||||
atom::Browser* browser = atom::Browser::Get();
|
||||
browser->UserActivityWasContinued(activity_type, *user_info);
|
||||
});
|
||||
[userActivity setNeedsSave:YES];
|
||||
}
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[[NSAppleEventManager sharedAppleEventManager]
|
||||
setEventHandler:self
|
||||
andSelector:@selector(handleURLEvent:withReplyEvent:)
|
||||
forEventClass:kInternetEventClass
|
||||
andEventID:kAEGetURL];
|
||||
|
||||
handoffLock_ = [NSCondition new];
|
||||
}
|
||||
|
||||
- (void)handleURLEvent:(NSAppleEventDescriptor*)event
|
||||
@@ -72,6 +143,9 @@
|
||||
bool enableAccessibility = ([self voiceOverEnabled] && [value boolValue]);
|
||||
[self updateAccessibilityEnabled:enableAccessibility];
|
||||
}
|
||||
else if ([attribute isEqualToString:@"AXManualAccessibility"]) {
|
||||
[self updateAccessibilityEnabled:[value boolValue]];
|
||||
}
|
||||
return [super accessibilitySetValue:value forAttribute:attribute];
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,36 @@
|
||||
#import "atom/browser/mac/atom_application.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
#include "base/allocator/allocator_shim.h"
|
||||
#include "base/allocator/features.h"
|
||||
#include "base/mac/mac_util.h"
|
||||
#include "base/mac/scoped_objc_class_swizzler.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
|
||||
#if BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM)
|
||||
// On macOS 10.12, the IME system attempts to allocate a 2^64 size buffer,
|
||||
// which would typically cause an OOM crash. To avoid this, the problematic
|
||||
// method is swizzled out and the make-OOM-fatal bit is disabled for the
|
||||
// duration of the original call. https://crbug.com/654695
|
||||
static base::mac::ScopedObjCClassSwizzler* g_swizzle_imk_input_session;
|
||||
@interface OOMDisabledIMKInputSession : NSObject
|
||||
@end
|
||||
@implementation OOMDisabledIMKInputSession
|
||||
- (void)_coreAttributesFromRange:(NSRange)range
|
||||
whichAttributes:(long long)attributes
|
||||
completionHandler:(void (^)(void))block {
|
||||
// The allocator flag is per-process, so other threads may temporarily
|
||||
// not have fatal OOM occur while this method executes, but it is better
|
||||
// than crashing when using IME.
|
||||
base::allocator::SetCallNewHandlerOnMallocFailure(false);
|
||||
g_swizzle_imk_input_session->GetOriginalImplementation()(self, _cmd, range,
|
||||
attributes, block);
|
||||
base::allocator::SetCallNewHandlerOnMallocFailure(true);
|
||||
}
|
||||
@end
|
||||
#endif // BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM)
|
||||
|
||||
@implementation AtomApplicationDelegate
|
||||
|
||||
- (void)setApplicationDockMenu:(atom::AtomMenuModel*)model {
|
||||
@@ -35,6 +62,16 @@
|
||||
std::unique_ptr<base::DictionaryValue> empty_info(new base::DictionaryValue);
|
||||
atom::Browser::Get()->DidFinishLaunching(*empty_info);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM)
|
||||
// Disable fatal OOM to hack around an OS bug https://crbug.com/654695.
|
||||
if (base::mac::IsOS10_12()) {
|
||||
g_swizzle_imk_input_session = new base::mac::ScopedObjCClassSwizzler(
|
||||
NSClassFromString(@"IMKInputSession"),
|
||||
[OOMDisabledIMKInputSession class],
|
||||
@selector(_coreAttributesFromRange:whichAttributes:completionHandler:));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (NSMenu*)applicationDockMenu:(NSApplication*)sender {
|
||||
@@ -81,6 +118,21 @@ continueUserActivity:(NSUserActivity*)userActivity
|
||||
return browser->ContinueUserActivity(activity_type, *user_info) ? YES : NO;
|
||||
}
|
||||
|
||||
- (BOOL)application:(NSApplication*)application willContinueUserActivityWithType:(NSString*)userActivityType {
|
||||
std::string activity_type(base::SysNSStringToUTF8(userActivityType));
|
||||
|
||||
atom::Browser* browser = atom::Browser::Get();
|
||||
return browser->WillContinueUserActivity(activity_type) ? YES : NO;
|
||||
}
|
||||
|
||||
- (void)application:(NSApplication*)application didFailToContinueUserActivityWithType:(NSString*)userActivityType error:(NSError*)error {
|
||||
std::string activity_type(base::SysNSStringToUTF8(userActivityType));
|
||||
std::string error_message(base::SysNSStringToUTF8([error localizedDescription]));
|
||||
|
||||
atom::Browser* browser = atom::Browser::Get();
|
||||
browser->DidFailToContinueUserActivity(activity_type, error_message);
|
||||
}
|
||||
|
||||
- (IBAction)newWindowForTab:(id)sender {
|
||||
atom::Browser::Get()->NewWindowForTab();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
|
||||
#include "base/json/json_writer.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
|
||||
@@ -45,14 +46,14 @@ std::unique_ptr<base::ListValue> NSArrayToListValue(NSArray* arr) {
|
||||
if (sub_arr)
|
||||
result->Append(std::move(sub_arr));
|
||||
else
|
||||
result->Append(base::Value::CreateNullValue());
|
||||
result->Append(base::MakeUnique<base::Value>());
|
||||
} else if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
std::unique_ptr<base::DictionaryValue> sub_dict =
|
||||
NSDictionaryToDictionaryValue(value);
|
||||
if (sub_dict)
|
||||
result->Append(std::move(sub_dict));
|
||||
else
|
||||
result->Append(base::Value::CreateNullValue());
|
||||
result->Append(base::MakeUnique<base::Value>());
|
||||
} else {
|
||||
result->AppendString(base::SysNSStringToUTF8([value description]));
|
||||
}
|
||||
@@ -104,7 +105,7 @@ std::unique_ptr<base::DictionaryValue> NSDictionaryToDictionaryValue(
|
||||
result->SetWithoutPathExpansion(str_key, std::move(sub_arr));
|
||||
else
|
||||
result->SetWithoutPathExpansion(str_key,
|
||||
base::Value::CreateNullValue());
|
||||
base::MakeUnique<base::Value>());
|
||||
} else if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
std::unique_ptr<base::DictionaryValue> sub_dict =
|
||||
NSDictionaryToDictionaryValue(value);
|
||||
@@ -112,7 +113,7 @@ std::unique_ptr<base::DictionaryValue> NSDictionaryToDictionaryValue(
|
||||
result->SetWithoutPathExpansion(str_key, std::move(sub_dict));
|
||||
else
|
||||
result->SetWithoutPathExpansion(str_key,
|
||||
base::Value::CreateNullValue());
|
||||
base::MakeUnique<base::Value>());
|
||||
} else {
|
||||
result->SetStringWithoutPathExpansion(
|
||||
str_key,
|
||||
|
||||
@@ -43,10 +43,20 @@ const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
|
||||
- (void)mouseDown:(NSEvent *)event
|
||||
{
|
||||
if ([self.window respondsToSelector:@selector(performWindowDragWithEvent)]) {
|
||||
// According to Google, using performWindowDragWithEvent:
|
||||
// does not generate a NSWindowWillMoveNotification. Hence post one.
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName:NSWindowWillMoveNotification
|
||||
object:self];
|
||||
|
||||
[self.window performWindowDragWithEvent:event];
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.window.styleMask & NSFullScreenWindowMask) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.initialLocation = [event locationInWindow];
|
||||
}
|
||||
|
||||
@@ -56,17 +66,53 @@ const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.window.styleMask & NSFullScreenWindowMask) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSPoint currentLocation = [NSEvent mouseLocation];
|
||||
NSPoint newOrigin;
|
||||
|
||||
NSRect screenFrame = [[NSScreen mainScreen] frame];
|
||||
NSSize screenSize = screenFrame.size;
|
||||
NSRect windowFrame = [self.window frame];
|
||||
NSSize windowSize = windowFrame.size;
|
||||
|
||||
newOrigin.x = currentLocation.x - self.initialLocation.x;
|
||||
newOrigin.y = currentLocation.y - self.initialLocation.y;
|
||||
|
||||
BOOL inMenuBar = (newOrigin.y + windowSize.height) > (screenFrame.origin.y + screenSize.height);
|
||||
BOOL screenAboveMainScreen = false;
|
||||
|
||||
if (inMenuBar) {
|
||||
for (NSScreen *screen in [NSScreen screens]) {
|
||||
NSRect currentScreenFrame = [screen frame];
|
||||
BOOL isHigher = currentScreenFrame.origin.y > screenFrame.origin.y;
|
||||
|
||||
// If there's another screen that is generally above the current screen,
|
||||
// we'll draw a new rectangle that is just above the current screen. If the
|
||||
// "higher" screen intersects with this rectangle, we'll allow drawing above
|
||||
// the menubar.
|
||||
if (isHigher) {
|
||||
NSRect aboveScreenRect = NSMakeRect(
|
||||
screenFrame.origin.x,
|
||||
screenFrame.origin.y + screenFrame.size.height - 10,
|
||||
screenFrame.size.width,
|
||||
200
|
||||
);
|
||||
|
||||
BOOL screenAboveIntersects = NSIntersectsRect(currentScreenFrame, aboveScreenRect);
|
||||
|
||||
if (screenAboveIntersects) {
|
||||
screenAboveMainScreen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Don't let window get dragged up under the menu bar
|
||||
if ((newOrigin.y + windowFrame.size.height) > (screenFrame.origin.y + screenFrame.size.height)) {
|
||||
if (inMenuBar && !screenAboveMainScreen) {
|
||||
newOrigin.y = screenFrame.origin.y + (screenFrame.size.height - windowFrame.size.height);
|
||||
}
|
||||
|
||||
|
||||
@@ -159,6 +159,10 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
|
||||
if (options.Get(options::kHasShadow, &has_shadow)) {
|
||||
SetHasShadow(has_shadow);
|
||||
}
|
||||
double opacity;
|
||||
if (options.Get(options::kOpacity, &opacity)) {
|
||||
SetOpacity(opacity);
|
||||
}
|
||||
bool top;
|
||||
if (options.Get(options::kAlwaysOnTop, &top) && top) {
|
||||
SetAlwaysOnTop(true);
|
||||
@@ -336,6 +340,24 @@ void NativeWindow::SetParentWindow(NativeWindow* parent) {
|
||||
void NativeWindow::SetAutoHideCursor(bool auto_hide) {
|
||||
}
|
||||
|
||||
void NativeWindow::SelectPreviousTab() {
|
||||
}
|
||||
|
||||
void NativeWindow::SelectNextTab() {
|
||||
}
|
||||
|
||||
void NativeWindow::MergeAllWindows() {
|
||||
}
|
||||
|
||||
void NativeWindow::MoveTabToNewWindow() {
|
||||
}
|
||||
|
||||
void NativeWindow::ToggleTabBar() {
|
||||
}
|
||||
|
||||
void NativeWindow::AddTabbedWindow(NativeWindow* window) {
|
||||
}
|
||||
|
||||
void NativeWindow::SetVibrancy(const std::string& filename) {
|
||||
}
|
||||
|
||||
|
||||
@@ -134,16 +134,20 @@ class NativeWindow : public base::SupportsUserData,
|
||||
virtual std::string GetTitle() = 0;
|
||||
virtual void FlashFrame(bool flash) = 0;
|
||||
virtual void SetSkipTaskbar(bool skip) = 0;
|
||||
virtual void SetSimpleFullScreen(bool simple_fullscreen) = 0;
|
||||
virtual bool IsSimpleFullScreen() = 0;
|
||||
virtual void SetKiosk(bool kiosk) = 0;
|
||||
virtual bool IsKiosk() = 0;
|
||||
virtual void SetBackgroundColor(const std::string& color_name) = 0;
|
||||
virtual void SetHasShadow(bool has_shadow) = 0;
|
||||
virtual bool HasShadow() = 0;
|
||||
virtual void SetOpacity(const double opacity) = 0;
|
||||
virtual double GetOpacity() = 0;
|
||||
virtual void SetRepresentedFilename(const std::string& filename);
|
||||
virtual std::string GetRepresentedFilename();
|
||||
virtual void SetDocumentEdited(bool edited);
|
||||
virtual bool IsDocumentEdited();
|
||||
virtual void SetIgnoreMouseEvents(bool ignore) = 0;
|
||||
virtual void SetIgnoreMouseEvents(bool ignore, bool forward) = 0;
|
||||
virtual void SetContentProtection(bool enable) = 0;
|
||||
virtual void SetFocusable(bool focusable);
|
||||
virtual void SetMenu(AtomMenuModel* menu);
|
||||
@@ -182,6 +186,14 @@ class NativeWindow : public base::SupportsUserData,
|
||||
virtual void RefreshTouchBarItem(const std::string& item_id);
|
||||
virtual void SetEscapeTouchBarItem(const mate::PersistentDictionary& item);
|
||||
|
||||
// Native Tab API
|
||||
virtual void SelectPreviousTab();
|
||||
virtual void SelectNextTab();
|
||||
virtual void MergeAllWindows();
|
||||
virtual void MoveTabToNewWindow();
|
||||
virtual void ToggleTabBar();
|
||||
virtual void AddTabbedWindow(NativeWindow* window);
|
||||
|
||||
// Webview APIs.
|
||||
virtual void FocusOnWebView();
|
||||
virtual void BlurWebView();
|
||||
|
||||
@@ -76,16 +76,20 @@ class NativeWindowMac : public NativeWindow,
|
||||
std::string GetTitle() override;
|
||||
void FlashFrame(bool flash) override;
|
||||
void SetSkipTaskbar(bool skip) override;
|
||||
void SetSimpleFullScreen(bool simple_fullscreen) override;
|
||||
bool IsSimpleFullScreen() override;
|
||||
void SetKiosk(bool kiosk) override;
|
||||
bool IsKiosk() override;
|
||||
void SetBackgroundColor(const std::string& color_name) override;
|
||||
void SetHasShadow(bool has_shadow) override;
|
||||
bool HasShadow() override;
|
||||
void SetOpacity(const double opacity) override;
|
||||
double GetOpacity() override;
|
||||
void SetRepresentedFilename(const std::string& filename) override;
|
||||
std::string GetRepresentedFilename() override;
|
||||
void SetDocumentEdited(bool edited) override;
|
||||
bool IsDocumentEdited() override;
|
||||
void SetIgnoreMouseEvents(bool ignore) override;
|
||||
void SetIgnoreMouseEvents(bool ignore, bool) override;
|
||||
void SetContentProtection(bool enable) override;
|
||||
void SetBrowserView(NativeBrowserView* browser_view) override;
|
||||
void SetParentWindow(NativeWindow* parent) override;
|
||||
@@ -101,6 +105,13 @@ class NativeWindowMac : public NativeWindow,
|
||||
|
||||
void SetAutoHideCursor(bool auto_hide) override;
|
||||
|
||||
void SelectPreviousTab() override;
|
||||
void SelectNextTab() override;
|
||||
void MergeAllWindows() override;
|
||||
void MoveTabToNewWindow() override;
|
||||
void ToggleTabBar() override;
|
||||
void AddTabbedWindow(NativeWindow* window) override;
|
||||
|
||||
void SetVibrancy(const std::string& type) override;
|
||||
void SetTouchBar(
|
||||
const std::vector<mate::PersistentDictionary>& items) override;
|
||||
@@ -135,6 +146,8 @@ class NativeWindowMac : public NativeWindow,
|
||||
|
||||
bool fullscreen_window_title() const { return fullscreen_window_title_; }
|
||||
|
||||
bool simple_fullscreen() const { return always_simple_fullscreen_; }
|
||||
|
||||
protected:
|
||||
// Return a vector of non-draggable regions that fill a window of size
|
||||
// |width| by |height|, but leave gaps where the window should be draggable.
|
||||
@@ -148,6 +161,7 @@ class NativeWindowMac : public NativeWindow,
|
||||
void UpdateDraggableRegions(
|
||||
const std::vector<DraggableRegion>& regions) override;
|
||||
|
||||
void InternalSetParentWindow(NativeWindow* parent, bool attach);
|
||||
void ShowWindowButton(NSWindowButton button);
|
||||
|
||||
void InstallView();
|
||||
@@ -189,6 +203,17 @@ class NativeWindowMac : public NativeWindow,
|
||||
// The "titleBarStyle" option.
|
||||
TitleBarStyle title_bar_style_;
|
||||
|
||||
// Simple (pre-Lion) Fullscreen Settings
|
||||
bool always_simple_fullscreen_;
|
||||
bool is_simple_fullscreen_;
|
||||
bool was_maximizable_;
|
||||
bool was_movable_;
|
||||
NSRect original_frame_;
|
||||
NSUInteger simple_fullscreen_mask_;
|
||||
|
||||
// The presentation options before entering simple fullscreen mode.
|
||||
NSApplicationPresentationOptions simple_fullscreen_options_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NativeWindowMac);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "atom/browser/native_window_mac.h"
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
#include <Quartz/Quartz.h>
|
||||
#include <string>
|
||||
|
||||
@@ -173,6 +174,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
atom::NativeWindowMac* shell_;
|
||||
bool is_zooming_;
|
||||
int level_;
|
||||
bool is_resizable_;
|
||||
}
|
||||
- (id)initWithShell:(atom::NativeWindowMac*)shell;
|
||||
@end
|
||||
@@ -335,6 +337,9 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
}
|
||||
|
||||
- (void)windowWillEnterFullScreen:(NSNotification*)notification {
|
||||
// Setting resizable to true before entering fullscreen
|
||||
is_resizable_ = shell_->IsResizable();
|
||||
shell_->SetResizable(true);
|
||||
// Hide the native toolbar before entering fullscreen, so there is no visual
|
||||
// artifacts.
|
||||
if (base::mac::IsAtLeastOS10_10() &&
|
||||
@@ -394,6 +399,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
}
|
||||
|
||||
- (void)windowDidExitFullScreen:(NSNotification*)notification {
|
||||
shell_->SetResizable(is_resizable_);
|
||||
shell_->NotifyWindowLeaveFullScreen();
|
||||
}
|
||||
|
||||
@@ -460,7 +466,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
|
||||
@end
|
||||
|
||||
#if !defined(MAC_OS_X_VERSION_10_12)
|
||||
#if !defined(AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER)
|
||||
|
||||
enum {
|
||||
NSWindowTabbingModeDisallowed = 2
|
||||
@@ -469,9 +475,15 @@ enum {
|
||||
@interface NSWindow (SierraSDK)
|
||||
- (void)setTabbingMode:(NSInteger)mode;
|
||||
- (void)setTabbingIdentifier:(NSString*)identifier;
|
||||
- (void)addTabbedWindow:(NSWindow*)window ordered:(NSWindowOrderingMode)ordered;
|
||||
- (IBAction)selectPreviousTab:(id)sender;
|
||||
- (IBAction)selectNextTab:(id)sender;
|
||||
- (IBAction)mergeAllWindows:(id)sender;
|
||||
- (IBAction)moveTabToNewWindow:(id)sender;
|
||||
- (IBAction)toggleTabBar:(id)sender;
|
||||
@end
|
||||
|
||||
#endif // MAC_OS_X_VERSION_10_12
|
||||
#endif
|
||||
|
||||
@interface AtomNSWindow : EventDispatchingWindow<QLPreviewPanelDataSource, QLPreviewPanelDelegate, NSTouchBarDelegate> {
|
||||
@private
|
||||
@@ -720,6 +732,13 @@ enum {
|
||||
[super performClose:sender];
|
||||
}
|
||||
|
||||
- (void)toggleFullScreen:(id)sender {
|
||||
if (shell_->simple_fullscreen())
|
||||
shell_->SetSimpleFullScreen(!shell_->IsSimpleFullScreen());
|
||||
else
|
||||
[super toggleFullScreen:sender];
|
||||
}
|
||||
|
||||
- (void)performMiniaturize:(id)sender {
|
||||
if (shell_->title_bar_style() == atom::NativeWindowMac::CUSTOM_BUTTONS_ON_HOVER)
|
||||
[self miniaturize:self];
|
||||
@@ -819,7 +838,9 @@ NativeWindowMac::NativeWindowMac(
|
||||
zoom_to_page_width_(false),
|
||||
fullscreen_window_title_(false),
|
||||
attention_request_id_(0),
|
||||
title_bar_style_(NORMAL) {
|
||||
title_bar_style_(NORMAL),
|
||||
always_simple_fullscreen_(false),
|
||||
is_simple_fullscreen_(false) {
|
||||
int width = 800, height = 600;
|
||||
options.Get(options::kWidth, &width);
|
||||
options.Get(options::kHeight, &height);
|
||||
@@ -965,6 +986,8 @@ NativeWindowMac::NativeWindowMac(
|
||||
|
||||
options.Get(options::kFullscreenWindowTitle, &fullscreen_window_title_);
|
||||
|
||||
options.Get(options::kSimpleFullScreen, &always_simple_fullscreen_);
|
||||
|
||||
// Enable the NSView to accept first mouse event.
|
||||
bool acceptsFirstMouse = false;
|
||||
options.Get(options::kAcceptFirstMouse, &acceptsFirstMouse);
|
||||
@@ -1065,6 +1088,10 @@ void NativeWindowMac::Show() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reattach the window to the parent to actually show it.
|
||||
if (parent())
|
||||
InternalSetParentWindow(parent(), true);
|
||||
|
||||
// This method is supposed to put focus on window, however if the app does not
|
||||
// have focus then "makeKeyAndOrderFront" will only show the window.
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
@@ -1073,6 +1100,10 @@ void NativeWindowMac::Show() {
|
||||
}
|
||||
|
||||
void NativeWindowMac::ShowInactive() {
|
||||
// Reattach the window to the parent to actually show it.
|
||||
if (parent())
|
||||
InternalSetParentWindow(parent(), true);
|
||||
|
||||
[window_ orderFrontRegardless];
|
||||
}
|
||||
|
||||
@@ -1083,6 +1114,10 @@ void NativeWindowMac::Hide() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Deattach the window from the parent before.
|
||||
if (parent())
|
||||
InternalSetParentWindow(parent(), false);
|
||||
|
||||
[window_ orderOut:nil];
|
||||
}
|
||||
|
||||
@@ -1351,6 +1386,80 @@ void NativeWindowMac::FlashFrame(bool flash) {
|
||||
void NativeWindowMac::SetSkipTaskbar(bool skip) {
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||
NSWindow* window = GetNativeWindow();
|
||||
|
||||
if (simple_fullscreen && !is_simple_fullscreen_) {
|
||||
is_simple_fullscreen_ = true;
|
||||
|
||||
// Take note of the current window size
|
||||
original_frame_ = [window frame];
|
||||
|
||||
simple_fullscreen_options_ = [NSApp currentSystemPresentationOptions];
|
||||
simple_fullscreen_mask_ = [window styleMask];
|
||||
|
||||
// We can simulate the pre-Lion fullscreen by auto-hiding the dock and menu bar
|
||||
NSApplicationPresentationOptions options =
|
||||
NSApplicationPresentationAutoHideDock +
|
||||
NSApplicationPresentationAutoHideMenuBar;
|
||||
[NSApp setPresentationOptions:options];
|
||||
|
||||
was_maximizable_ = IsMaximizable();
|
||||
was_movable_ = IsMovable();
|
||||
|
||||
NSRect fullscreenFrame = [window.screen frame];
|
||||
|
||||
if ( !fullscreen_window_title() ) {
|
||||
// Hide the titlebar
|
||||
SetStyleMask(false, NSTitledWindowMask);
|
||||
|
||||
// Resize the window to accomodate the _entire_ screen size
|
||||
fullscreenFrame.size.height -= [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
|
||||
} else {
|
||||
// No need to hide the title, but we should still hide the window buttons
|
||||
[[window standardWindowButton:NSWindowZoomButton] setHidden:YES];
|
||||
[[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
|
||||
[[window standardWindowButton:NSWindowCloseButton] setHidden:YES];
|
||||
}
|
||||
|
||||
[window setFrame:fullscreenFrame display: YES animate: YES];
|
||||
|
||||
// Fullscreen windows can't be resized, minimized, maximized, or moved
|
||||
SetMinimizable(false);
|
||||
SetResizable(false);
|
||||
SetMaximizable(false);
|
||||
SetMovable(false);
|
||||
} else if (!simple_fullscreen && is_simple_fullscreen_) {
|
||||
is_simple_fullscreen_ = false;
|
||||
|
||||
if ( !fullscreen_window_title() ) {
|
||||
// Restore the titlebar
|
||||
SetStyleMask(true, NSTitledWindowMask);
|
||||
} else {
|
||||
// Show the window buttons
|
||||
[[window standardWindowButton:NSWindowZoomButton] setHidden:NO];
|
||||
[[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:NO];
|
||||
[[window standardWindowButton:NSWindowCloseButton] setHidden:NO];
|
||||
}
|
||||
|
||||
[window setFrame:original_frame_ display: YES animate: YES];
|
||||
|
||||
[NSApp setPresentationOptions:simple_fullscreen_options_];
|
||||
|
||||
// Restore original style mask
|
||||
ScopedDisableResize disable_resize;
|
||||
[window_ setStyleMask:simple_fullscreen_mask_];
|
||||
|
||||
// Restore window manipulation abilities
|
||||
SetMaximizable(was_maximizable_);
|
||||
SetMovable(was_movable_);
|
||||
}
|
||||
}
|
||||
|
||||
bool NativeWindowMac::IsSimpleFullScreen() {
|
||||
return is_simple_fullscreen_;
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetKiosk(bool kiosk) {
|
||||
if (kiosk && !is_kiosk_) {
|
||||
kiosk_options_ = [NSApp currentSystemPresentationOptions];
|
||||
@@ -1396,6 +1505,14 @@ bool NativeWindowMac::HasShadow() {
|
||||
return [window_ hasShadow];
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetOpacity(const double opacity) {
|
||||
[window_ setAlphaValue:opacity];
|
||||
}
|
||||
|
||||
double NativeWindowMac::GetOpacity() {
|
||||
return [window_ alphaValue];
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetRepresentedFilename(const std::string& filename) {
|
||||
[window_ setRepresentedFilename:base::SysUTF8ToNSString(filename)];
|
||||
}
|
||||
@@ -1412,7 +1529,7 @@ bool NativeWindowMac::IsDocumentEdited() {
|
||||
return [window_ isDocumentEdited];
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetIgnoreMouseEvents(bool ignore) {
|
||||
void NativeWindowMac::SetIgnoreMouseEvents(bool ignore, bool) {
|
||||
[window_ setIgnoresMouseEvents:ignore];
|
||||
}
|
||||
|
||||
@@ -1442,18 +1559,7 @@ void NativeWindowMac::SetBrowserView(NativeBrowserView* browser_view) {
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
|
||||
if (is_modal())
|
||||
return;
|
||||
|
||||
NativeWindow::SetParentWindow(parent);
|
||||
|
||||
// Remove current parent window.
|
||||
if ([window_ parentWindow])
|
||||
[[window_ parentWindow] removeChildWindow:window_];
|
||||
|
||||
// Set new current window.
|
||||
if (parent)
|
||||
[parent->GetNativeWindow() addChildWindow:window_ ordered:NSWindowAbove];
|
||||
InternalSetParentWindow(parent, IsVisible());
|
||||
}
|
||||
|
||||
gfx::NativeView NativeWindowMac::GetNativeView() const {
|
||||
@@ -1523,6 +1629,42 @@ void NativeWindowMac::SetAutoHideCursor(bool auto_hide) {
|
||||
[window_ setDisableAutoHideCursor:!auto_hide];
|
||||
}
|
||||
|
||||
void NativeWindowMac::SelectPreviousTab() {
|
||||
if ([window_ respondsToSelector:@selector(selectPreviousTab:)]) {
|
||||
[window_ selectPreviousTab:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::SelectNextTab() {
|
||||
if ([window_ respondsToSelector:@selector(selectNextTab:)]) {
|
||||
[window_ selectNextTab:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::MergeAllWindows() {
|
||||
if ([window_ respondsToSelector:@selector(mergeAllWindows:)]) {
|
||||
[window_ mergeAllWindows:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::MoveTabToNewWindow() {
|
||||
if ([window_ respondsToSelector:@selector(moveTabToNewWindow:)]) {
|
||||
[window_ moveTabToNewWindow:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::ToggleTabBar() {
|
||||
if ([window_ respondsToSelector:@selector(toggleTabBar:)]) {
|
||||
[window_ toggleTabBar:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::AddTabbedWindow(NativeWindow* window) {
|
||||
if ([window_ respondsToSelector:@selector(addTabbedWindow:ordered:)]) {
|
||||
[window_ addTabbedWindow:window->GetNativeWindow() ordered:NSWindowAbove];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetVibrancy(const std::string& type) {
|
||||
if (!base::mac::IsAtLeastOS10_10()) return;
|
||||
|
||||
@@ -1604,10 +1746,10 @@ void NativeWindowMac::SetEscapeTouchBarItem(const mate::PersistentDictionary& it
|
||||
}
|
||||
|
||||
void NativeWindowMac::OnInputEvent(const blink::WebInputEvent& event) {
|
||||
switch (event.type()) {
|
||||
case blink::WebInputEvent::GestureScrollBegin:
|
||||
case blink::WebInputEvent::GestureScrollUpdate:
|
||||
case blink::WebInputEvent::GestureScrollEnd:
|
||||
switch (event.GetType()) {
|
||||
case blink::WebInputEvent::kGestureScrollBegin:
|
||||
case blink::WebInputEvent::kGestureScrollUpdate:
|
||||
case blink::WebInputEvent::kGestureScrollEnd:
|
||||
this->NotifyWindowScrollTouchEdge();
|
||||
break;
|
||||
default:
|
||||
@@ -1672,6 +1814,26 @@ void NativeWindowMac::UpdateDraggableRegions(
|
||||
UpdateDraggableRegionViews(regions);
|
||||
}
|
||||
|
||||
void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent, bool attach) {
|
||||
if (is_modal())
|
||||
return;
|
||||
|
||||
NativeWindow::SetParentWindow(parent);
|
||||
|
||||
// Do not remove/add if we are already properly attached.
|
||||
if (attach && parent && [window_ parentWindow] == parent->GetNativeWindow())
|
||||
return;
|
||||
|
||||
// Remove current parent window.
|
||||
if ([window_ parentWindow])
|
||||
[[window_ parentWindow] removeChildWindow:window_];
|
||||
|
||||
// Set new parent window.
|
||||
// Note that this method will force the window to become visible.
|
||||
if (parent && attach)
|
||||
[parent->GetNativeWindow() addChildWindow:window_ ordered:NSWindowAbove];
|
||||
}
|
||||
|
||||
void NativeWindowMac::ShowWindowButton(NSWindowButton button) {
|
||||
auto view = [window_ standardWindowButton:button];
|
||||
[view.superview addSubview:view positioned:NSWindowAbove relativeTo:nil];
|
||||
|
||||
@@ -82,17 +82,17 @@ void FlipWindowStyle(HWND handle, bool on, DWORD flag) {
|
||||
#endif
|
||||
|
||||
bool IsAltKey(const content::NativeWebKeyboardEvent& event) {
|
||||
return event.windowsKeyCode == ui::VKEY_MENU;
|
||||
return event.windows_key_code == ui::VKEY_MENU;
|
||||
}
|
||||
|
||||
bool IsAltModifier(const content::NativeWebKeyboardEvent& event) {
|
||||
typedef content::NativeWebKeyboardEvent::Modifiers Modifiers;
|
||||
int modifiers = event.modifiers();
|
||||
modifiers &= ~Modifiers::NumLockOn;
|
||||
modifiers &= ~Modifiers::CapsLockOn;
|
||||
return (modifiers == Modifiers::AltKey) ||
|
||||
(modifiers == (Modifiers::AltKey | Modifiers::IsLeft)) ||
|
||||
(modifiers == (Modifiers::AltKey | Modifiers::IsRight));
|
||||
int modifiers = event.GetModifiers();
|
||||
modifiers &= ~Modifiers::kNumLockOn;
|
||||
modifiers &= ~Modifiers::kCapsLockOn;
|
||||
return (modifiers == Modifiers::kAltKey) ||
|
||||
(modifiers == (Modifiers::kAltKey | Modifiers::kIsLeft)) ||
|
||||
(modifiers == (Modifiers::kAltKey | Modifiers::kIsRight));
|
||||
}
|
||||
|
||||
#if defined(USE_X11)
|
||||
@@ -304,11 +304,16 @@ NativeWindowViews::NativeWindowViews(
|
||||
::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style);
|
||||
#endif
|
||||
|
||||
// TODO(zcbenz): This was used to force using native frame on Windows 2003, we
|
||||
// should check whether setting it in InitParams can work.
|
||||
if (has_frame()) {
|
||||
// TODO(zcbenz): This was used to force using native frame on Windows 2003,
|
||||
// we should check whether setting it in InitParams can work.
|
||||
window_->set_frame_type(views::Widget::FrameType::FRAME_TYPE_FORCE_NATIVE);
|
||||
window_->FrameTypeChanged();
|
||||
#if defined(OS_WIN)
|
||||
// thickFrame also works for normal window.
|
||||
if (!thick_frame_)
|
||||
FlipWindowStyle(GetAcceleratedWidget(), false, WS_THICKFRAME);
|
||||
#endif
|
||||
}
|
||||
|
||||
gfx::Size size = bounds.size();
|
||||
@@ -334,6 +339,11 @@ NativeWindowViews::NativeWindowViews(
|
||||
|
||||
NativeWindowViews::~NativeWindowViews() {
|
||||
window_->RemoveObserver(this);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Disable mouse forwarding to relinquish resources, should any be held.
|
||||
SetForwardMouseMessages(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void NativeWindowViews::Close() {
|
||||
@@ -572,6 +582,12 @@ gfx::Size NativeWindowViews::GetContentSize() {
|
||||
void NativeWindowViews::SetContentSizeConstraints(
|
||||
const extensions::SizeConstraints& size_constraints) {
|
||||
NativeWindow::SetContentSizeConstraints(size_constraints);
|
||||
#if defined(OS_WIN)
|
||||
// Changing size constraints would force adding the WS_THICKFRAME style, so
|
||||
// do nothing if thickFrame is false.
|
||||
if (!thick_frame_)
|
||||
return;
|
||||
#endif
|
||||
// widget_delegate() is only available after Init() is called, we make use of
|
||||
// this to determine whether native widget has initialized.
|
||||
if (window_ && window_->widget_delegate())
|
||||
@@ -584,7 +600,7 @@ void NativeWindowViews::SetContentSizeConstraints(
|
||||
|
||||
void NativeWindowViews::SetResizable(bool resizable) {
|
||||
#if defined(OS_WIN)
|
||||
if (has_frame())
|
||||
if (has_frame() && thick_frame_)
|
||||
FlipWindowStyle(GetAcceleratedWidget(), resizable, WS_THICKFRAME);
|
||||
#elif defined(USE_X11)
|
||||
if (resizable != resizable_) {
|
||||
@@ -754,6 +770,14 @@ void NativeWindowViews::SetSkipTaskbar(bool skip) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||
SetFullScreen(simple_fullscreen);
|
||||
}
|
||||
|
||||
bool NativeWindowViews::IsSimpleFullScreen() {
|
||||
return IsFullscreen();
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetKiosk(bool kiosk) {
|
||||
SetFullScreen(kiosk);
|
||||
}
|
||||
@@ -790,14 +814,41 @@ bool NativeWindowViews::HasShadow() {
|
||||
!= wm::ShadowElevation::NONE;
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetIgnoreMouseEvents(bool ignore) {
|
||||
void NativeWindowViews::SetOpacity(const double opacity) {
|
||||
#if defined(OS_WIN)
|
||||
HWND hwnd = GetAcceleratedWidget();
|
||||
if (!layered_) {
|
||||
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
ex_style |= WS_EX_LAYERED;
|
||||
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
||||
layered_ = true;
|
||||
}
|
||||
::SetLayeredWindowAttributes(hwnd, 0, opacity * 255, LWA_ALPHA);
|
||||
#endif
|
||||
opacity_ = opacity;
|
||||
}
|
||||
|
||||
double NativeWindowViews::GetOpacity() {
|
||||
return opacity_;
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetIgnoreMouseEvents(bool ignore, bool forward) {
|
||||
#if defined(OS_WIN)
|
||||
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
|
||||
if (ignore)
|
||||
ex_style |= (WS_EX_TRANSPARENT | WS_EX_LAYERED);
|
||||
else
|
||||
ex_style &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED);
|
||||
if (layered_)
|
||||
ex_style |= WS_EX_LAYERED;
|
||||
::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style);
|
||||
|
||||
// Forwarding is always disabled when not ignoring mouse messages.
|
||||
if (!ignore) {
|
||||
SetForwardMouseMessages(false);
|
||||
} else {
|
||||
SetForwardMouseMessages(forward);
|
||||
}
|
||||
#elif defined(USE_X11)
|
||||
if (ignore) {
|
||||
XRectangle r = {0, 0, 1, 1};
|
||||
@@ -1090,9 +1141,31 @@ void NativeWindowViews::OnWidgetBoundsChanged(
|
||||
if (widget != window_.get())
|
||||
return;
|
||||
|
||||
if (widget_size_ != bounds.size()) {
|
||||
// Note: We intentionally use `GetBounds()` instead of `bounds` to properly
|
||||
// handle minimized windows on Windows.
|
||||
const auto new_bounds = GetBounds();
|
||||
if (widget_size_ != new_bounds.size()) {
|
||||
if (browser_view_) {
|
||||
const auto flags = static_cast<NativeBrowserViewViews*>(browser_view_)
|
||||
->GetAutoResizeFlags();
|
||||
int width_delta = 0;
|
||||
int height_delta = 0;
|
||||
if (flags & kAutoResizeWidth) {
|
||||
width_delta = new_bounds.width() - widget_size_.width();
|
||||
}
|
||||
if (flags & kAutoResizeHeight) {
|
||||
height_delta = new_bounds.height() - widget_size_.height();
|
||||
}
|
||||
|
||||
auto* view = browser_view_->GetInspectableWebContentsView()->GetView();
|
||||
auto new_view_size = view->size();
|
||||
new_view_size.set_width(new_view_size.width() + width_delta);
|
||||
new_view_size.set_height(new_view_size.height() + height_delta);
|
||||
view->SetSize(new_view_size);
|
||||
}
|
||||
|
||||
NotifyWindowResize();
|
||||
widget_size_ = bounds.size();
|
||||
widget_size_ = new_bounds.size();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1252,15 +1325,15 @@ void NativeWindowViews::HandleKeyboardEvent(
|
||||
// Show accelerator when "Alt" is pressed.
|
||||
if (menu_bar_visible_ && IsAltKey(event))
|
||||
menu_bar_->SetAcceleratorVisibility(
|
||||
event.type() == blink::WebInputEvent::RawKeyDown);
|
||||
event.GetType() == blink::WebInputEvent::kRawKeyDown);
|
||||
|
||||
// Show the submenu when "Alt+Key" is pressed.
|
||||
if (event.type() == blink::WebInputEvent::RawKeyDown && !IsAltKey(event) &&
|
||||
IsAltModifier(event)) {
|
||||
if (event.GetType() == blink::WebInputEvent::kRawKeyDown &&
|
||||
!IsAltKey(event) && IsAltModifier(event)) {
|
||||
if (!menu_bar_visible_ &&
|
||||
(menu_bar_->GetAcceleratorIndex(event.windowsKeyCode) != -1))
|
||||
(menu_bar_->GetAcceleratorIndex(event.windows_key_code) != -1))
|
||||
SetMenuBarVisibility(true);
|
||||
menu_bar_->ActivateAccelerator(event.windowsKeyCode);
|
||||
menu_bar_->ActivateAccelerator(event.windows_key_code);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1268,11 +1341,11 @@ void NativeWindowViews::HandleKeyboardEvent(
|
||||
return;
|
||||
|
||||
// Toggle the menu bar only when a single Alt is released.
|
||||
if (event.type() == blink::WebInputEvent::RawKeyDown && IsAltKey(event)) {
|
||||
if (event.GetType() == blink::WebInputEvent::kRawKeyDown && IsAltKey(event)) {
|
||||
// When a single Alt is pressed:
|
||||
menu_bar_alt_pressed_ = true;
|
||||
} else if (event.type() == blink::WebInputEvent::KeyUp && IsAltKey(event) &&
|
||||
menu_bar_alt_pressed_) {
|
||||
} else if (event.GetType() == blink::WebInputEvent::kKeyUp &&
|
||||
IsAltKey(event) && menu_bar_alt_pressed_) {
|
||||
// When a single Alt is released right after a Alt is pressed:
|
||||
menu_bar_alt_pressed_ = false;
|
||||
SetMenuBarVisibility(!menu_bar_visible_);
|
||||
@@ -1311,32 +1384,11 @@ void NativeWindowViews::Layout() {
|
||||
menu_bar_->SetBoundsRect(menu_bar_bounds);
|
||||
}
|
||||
|
||||
const auto old_web_view_size = web_view_ ? web_view_->size() : gfx::Size();
|
||||
if (web_view_) {
|
||||
web_view_->SetBoundsRect(
|
||||
gfx::Rect(0, menu_bar_bounds.height(), size.width(),
|
||||
size.height() - menu_bar_bounds.height()));
|
||||
}
|
||||
const auto new_web_view_size = web_view_ ? web_view_->size() : gfx::Size();
|
||||
|
||||
if (browser_view_) {
|
||||
const auto flags = static_cast<NativeBrowserViewViews*>(browser_view_)
|
||||
->GetAutoResizeFlags();
|
||||
int width_delta = 0;
|
||||
int height_delta = 0;
|
||||
if (flags & kAutoResizeWidth) {
|
||||
width_delta = new_web_view_size.width() - old_web_view_size.width();
|
||||
}
|
||||
if (flags & kAutoResizeHeight) {
|
||||
height_delta = new_web_view_size.height() - old_web_view_size.height();
|
||||
}
|
||||
|
||||
auto* view = browser_view_->GetInspectableWebContentsView()->GetView();
|
||||
auto new_view_size = view->size();
|
||||
new_view_size.set_width(new_view_size.width() + width_delta);
|
||||
new_view_size.set_height(new_view_size.height() + height_delta);
|
||||
view->SetSize(new_view_size);
|
||||
}
|
||||
}
|
||||
|
||||
gfx::Size NativeWindowViews::GetMinimumSize() const {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -96,12 +97,16 @@ class NativeWindowViews : public NativeWindow,
|
||||
std::string GetTitle() override;
|
||||
void FlashFrame(bool flash) override;
|
||||
void SetSkipTaskbar(bool skip) override;
|
||||
void SetSimpleFullScreen(bool simple_fullscreen) override;
|
||||
bool IsSimpleFullScreen() override;
|
||||
void SetKiosk(bool kiosk) override;
|
||||
bool IsKiosk() override;
|
||||
void SetBackgroundColor(const std::string& color_name) override;
|
||||
void SetHasShadow(bool has_shadow) override;
|
||||
bool HasShadow() override;
|
||||
void SetIgnoreMouseEvents(bool ignore) override;
|
||||
void SetOpacity(const double opacity) override;
|
||||
double GetOpacity() override;
|
||||
void SetIgnoreMouseEvents(bool ignore, bool forward) override;
|
||||
void SetContentProtection(bool enable) override;
|
||||
void SetFocusable(bool focusable) override;
|
||||
void SetMenu(AtomMenuModel* menu_model) override;
|
||||
@@ -169,6 +174,12 @@ class NativeWindowViews : public NativeWindow,
|
||||
bool PreHandleMSG(
|
||||
UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override;
|
||||
void HandleSizeEvent(WPARAM w_param, LPARAM l_param);
|
||||
void SetForwardMouseMessages(bool forward);
|
||||
static LRESULT CALLBACK SubclassProc(
|
||||
HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param, UINT_PTR subclass_id,
|
||||
DWORD_PTR ref_data);
|
||||
static LRESULT CALLBACK MouseHookProc(
|
||||
int n_code, WPARAM w_param, LPARAM l_param);
|
||||
#endif
|
||||
|
||||
// NativeWindow:
|
||||
@@ -259,6 +270,13 @@ class NativeWindowViews : public NativeWindow,
|
||||
// The icons of window and taskbar.
|
||||
base::win::ScopedHICON window_icon_;
|
||||
base::win::ScopedHICON app_icon_;
|
||||
|
||||
// The set of windows currently forwarding mouse messages.
|
||||
static std::set<NativeWindowViews*> forwarding_windows_;
|
||||
static HHOOK mouse_hook_;
|
||||
bool forwarding_mouse_messages_ = false;
|
||||
HWND legacy_window_ = NULL;
|
||||
bool layered_ = false;
|
||||
#endif
|
||||
|
||||
// Handles unhandled keyboard messages coming back from the renderer process.
|
||||
@@ -278,6 +296,7 @@ class NativeWindowViews : public NativeWindow,
|
||||
bool fullscreenable_;
|
||||
std::string title_;
|
||||
gfx::Size widget_size_;
|
||||
double opacity_ = 1.0;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NativeWindowViews);
|
||||
};
|
||||
|
||||
@@ -80,6 +80,9 @@ bool IsScreenReaderActive() {
|
||||
|
||||
} // namespace
|
||||
|
||||
std::set<NativeWindowViews*> NativeWindowViews::forwarding_windows_;
|
||||
HHOOK NativeWindowViews::mouse_hook_ = NULL;
|
||||
|
||||
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
|
||||
std::string command = AppCommandToString(command_id);
|
||||
NotifyWindowExecuteWindowsCommand(command);
|
||||
@@ -151,6 +154,16 @@ bool NativeWindowViews::PreHandleMSG(
|
||||
if (w_param) {
|
||||
NotifyWindowEndSession();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case WM_PARENTNOTIFY: {
|
||||
if (LOWORD(w_param) == WM_CREATE) {
|
||||
// Because of reasons regarding legacy drivers and stuff, a window that
|
||||
// matches the client area is created and used internally by Chromium.
|
||||
// This is used when forwarding mouse messages.
|
||||
legacy_window_ = reinterpret_cast<HWND>(l_param);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
@@ -207,4 +220,86 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetForwardMouseMessages(bool forward) {
|
||||
if (forward && !forwarding_mouse_messages_) {
|
||||
forwarding_mouse_messages_ = true;
|
||||
forwarding_windows_.insert(this);
|
||||
|
||||
// Subclassing is used to fix some issues when forwarding mouse messages;
|
||||
// see comments in |SubclassProc|.
|
||||
SetWindowSubclass(
|
||||
legacy_window_, SubclassProc, 1, reinterpret_cast<DWORD_PTR>(this));
|
||||
|
||||
if (!mouse_hook_) {
|
||||
mouse_hook_ = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, NULL, 0);
|
||||
}
|
||||
} else if (!forward && forwarding_mouse_messages_) {
|
||||
forwarding_mouse_messages_ = false;
|
||||
forwarding_windows_.erase(this);
|
||||
|
||||
RemoveWindowSubclass(legacy_window_, SubclassProc, 1);
|
||||
|
||||
if (forwarding_windows_.size() == 0) {
|
||||
UnhookWindowsHookEx(mouse_hook_);
|
||||
mouse_hook_ = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK NativeWindowViews::SubclassProc(
|
||||
HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param, UINT_PTR subclass_id,
|
||||
DWORD_PTR ref_data) {
|
||||
NativeWindowViews* window = reinterpret_cast<NativeWindowViews*>(ref_data);
|
||||
switch (msg) {
|
||||
case WM_MOUSELEAVE: {
|
||||
// When input is forwarded to underlying windows, this message is posted.
|
||||
// If not handled, it interferes with Chromium logic, causing for example
|
||||
// mouseleave events to fire. If those events are used to exit forward
|
||||
// mode, excessive flickering on for example hover items in underlying
|
||||
// windows can occur due to rapidly entering and leaving forwarding mode.
|
||||
// By consuming and ignoring the message, we're essentially telling
|
||||
// Chromium that we have not left the window despite somebody else getting
|
||||
// the messages. As to why this is catched for the legacy window and not
|
||||
// the actual browser window is simply that the legacy window somehow
|
||||
// makes use of these events; posting to the main window didn't work.
|
||||
if (window->forwarding_mouse_messages_) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefSubclassProc(hwnd, msg, w_param, l_param);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK NativeWindowViews::MouseHookProc(
|
||||
int n_code, WPARAM w_param, LPARAM l_param) {
|
||||
if (n_code < 0) {
|
||||
return CallNextHookEx(NULL, n_code, w_param, l_param);
|
||||
}
|
||||
|
||||
// Post a WM_MOUSEMOVE message for those windows whose client area contains
|
||||
// the cursor since they are in a state where they would otherwise ignore all
|
||||
// mouse input.
|
||||
if (w_param == WM_MOUSEMOVE) {
|
||||
for (auto window : forwarding_windows_) {
|
||||
// At first I considered enumerating windows to check whether the cursor
|
||||
// was directly above the window, but since nothing bad seems to happen
|
||||
// if we post the message even if some other window occludes it I have
|
||||
// just left it as is.
|
||||
RECT client_rect;
|
||||
GetClientRect(window->legacy_window_, &client_rect);
|
||||
POINT p = reinterpret_cast<MSLLHOOKSTRUCT*>(l_param)->pt;
|
||||
ScreenToClient(window->legacy_window_, &p);
|
||||
if (PtInRect(&client_rect, p)) {
|
||||
WPARAM w = 0; // No virtual keys pressed for our purposes
|
||||
LPARAM l = MAKELPARAM(p.x, p.y);
|
||||
PostMessage(window->legacy_window_, WM_MOUSEMOVE, w, l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CallNextHookEx(NULL, n_code, w_param, l_param);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -92,6 +92,7 @@ class CertVerifierRequest : public AtomCertVerifier::Request {
|
||||
std::unique_ptr<VerifyRequestParams> request(new VerifyRequestParams());
|
||||
request->hostname = params_.hostname();
|
||||
request->default_result = net::ErrorToString(error);
|
||||
request->error_code = error;
|
||||
request->certificate = params_.certificate();
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
|
||||
@@ -19,6 +19,7 @@ class CertVerifierRequest;
|
||||
struct VerifyRequestParams {
|
||||
std::string hostname;
|
||||
std::string default_result;
|
||||
int error_code;
|
||||
scoped_refptr<net::X509Certificate> certificate;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "brightray/browser/net/devtools_network_transaction.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
|
||||
using brightray::DevToolsNetworkTransaction;
|
||||
@@ -74,10 +76,23 @@ void ToDictionary(base::DictionaryValue* details, net::URLRequest* request) {
|
||||
FillRequestDetails(details, request);
|
||||
details->SetInteger("id", request->identifier());
|
||||
details->SetDouble("timestamp", base::Time::Now().ToDoubleT() * 1000);
|
||||
auto info = content::ResourceRequestInfo::ForRequest(request);
|
||||
details->SetString("resourceType",
|
||||
info ? ResourceTypeToString(info->GetResourceType())
|
||||
: "other");
|
||||
const auto* info = content::ResourceRequestInfo::ForRequest(request);
|
||||
if (info) {
|
||||
int process_id = info->GetChildID();
|
||||
int frame_id = info->GetRenderFrameID();
|
||||
auto* webContents = content::WebContents::FromRenderFrameHost(
|
||||
content::RenderFrameHost::FromID(process_id, frame_id));
|
||||
int webContentsId = atom::api::WebContents::GetIDFromWrappedClass(
|
||||
webContents);
|
||||
|
||||
// webContentsId must be greater than zero
|
||||
if (webContentsId)
|
||||
details->SetInteger("webContentsId", webContentsId);
|
||||
details->SetString("resourceType",
|
||||
ResourceTypeToString(info->GetResourceType()));
|
||||
} else {
|
||||
details->SetString("resourceType", "other");
|
||||
}
|
||||
}
|
||||
|
||||
void ToDictionary(base::DictionaryValue* details,
|
||||
|
||||
@@ -117,17 +117,13 @@ bool AtomURLRequestJobFactory::IsHandledProtocol(
|
||||
net::URLRequest::IsHandledProtocol(scheme);
|
||||
}
|
||||
|
||||
bool AtomURLRequestJobFactory::IsHandledURL(const GURL& url) const {
|
||||
if (!url.is_valid()) {
|
||||
bool AtomURLRequestJobFactory::IsSafeRedirectTarget(
|
||||
const GURL& location) const {
|
||||
if (!location.is_valid()) {
|
||||
// We handle error cases.
|
||||
return true;
|
||||
}
|
||||
return IsHandledProtocol(url.scheme());
|
||||
}
|
||||
|
||||
bool AtomURLRequestJobFactory::IsSafeRedirectTarget(
|
||||
const GURL& location) const {
|
||||
return IsHandledURL(location);
|
||||
return IsHandledProtocol(location.scheme());
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -55,7 +55,6 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const override;
|
||||
bool IsHandledProtocol(const std::string& scheme) const override;
|
||||
bool IsHandledURL(const GURL& url) const override;
|
||||
bool IsSafeRedirectTarget(const GURL& location) const override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -33,7 +33,7 @@ URLRequestBufferJob::URLRequestBufferJob(
|
||||
}
|
||||
|
||||
void URLRequestBufferJob::StartAsync(std::unique_ptr<base::Value> options) {
|
||||
const base::BinaryValue* binary = nullptr;
|
||||
const base::Value* binary = nullptr;
|
||||
if (options->IsType(base::Value::Type::DICTIONARY)) {
|
||||
base::DictionaryValue* dict =
|
||||
static_cast<base::DictionaryValue*>(options.get());
|
||||
|
||||
@@ -27,9 +27,9 @@ void NodeDebugger::Start() {
|
||||
node::DebugOptions options;
|
||||
for (auto& arg : base::CommandLine::ForCurrentProcess()->argv()) {
|
||||
#if defined(OS_WIN)
|
||||
options.ParseOption(base::UTF16ToUTF8(arg));
|
||||
options.ParseOption("Electron", base::UTF16ToUTF8(arg));
|
||||
#else
|
||||
options.ParseOption(arg);
|
||||
options.ParseOption("Electron", arg);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback_helpers.h"
|
||||
@@ -15,10 +17,10 @@
|
||||
#include "cc/output/copy_output_request.h"
|
||||
#include "cc/scheduler/delay_based_time_source.h"
|
||||
#include "components/display_compositor/gl_helper.h"
|
||||
#include "content/browser/renderer_host/compositor_resize_lock.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_delegate.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_frame_subscriber.h"
|
||||
#include "content/browser/renderer_host/resize_lock.h"
|
||||
#include "content/common/view_messages.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/context_factory.h"
|
||||
@@ -29,10 +31,10 @@
|
||||
#include "ui/compositor/layer_type.h"
|
||||
#include "ui/events/base_event_utils.h"
|
||||
#include "ui/events/event_constants.h"
|
||||
#include "ui/events/latency_info.h"
|
||||
#include "ui/gfx/geometry/dip_util.h"
|
||||
#include "ui/gfx/native_widget_types.h"
|
||||
#include "ui/gfx/skbitmap_operations.h"
|
||||
#include "ui/latency/latency_info.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -43,23 +45,23 @@ const int kFrameRetryLimit = 2;
|
||||
|
||||
ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
||||
ui::EventType type = ui::EventType::ET_UNKNOWN;
|
||||
switch (event.type()) {
|
||||
case blink::WebInputEvent::MouseDown:
|
||||
switch (event.GetType()) {
|
||||
case blink::WebInputEvent::kMouseDown:
|
||||
type = ui::EventType::ET_MOUSE_PRESSED;
|
||||
break;
|
||||
case blink::WebInputEvent::MouseUp:
|
||||
case blink::WebInputEvent::kMouseUp:
|
||||
type = ui::EventType::ET_MOUSE_RELEASED;
|
||||
break;
|
||||
case blink::WebInputEvent::MouseMove:
|
||||
case blink::WebInputEvent::kMouseMove:
|
||||
type = ui::EventType::ET_MOUSE_MOVED;
|
||||
break;
|
||||
case blink::WebInputEvent::MouseEnter:
|
||||
case blink::WebInputEvent::kMouseEnter:
|
||||
type = ui::EventType::ET_MOUSE_ENTERED;
|
||||
break;
|
||||
case blink::WebInputEvent::MouseLeave:
|
||||
case blink::WebInputEvent::kMouseLeave:
|
||||
type = ui::EventType::ET_MOUSE_EXITED;
|
||||
break;
|
||||
case blink::WebInputEvent::MouseWheel:
|
||||
case blink::WebInputEvent::kMouseWheel:
|
||||
type = ui::EventType::ET_MOUSEWHEEL;
|
||||
break;
|
||||
default:
|
||||
@@ -69,19 +71,19 @@ ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
||||
|
||||
int button_flags = 0;
|
||||
switch (event.button) {
|
||||
case blink::WebMouseEvent::Button::X1:
|
||||
case blink::WebMouseEvent::Button::kBack:
|
||||
button_flags |= ui::EventFlags::EF_BACK_MOUSE_BUTTON;
|
||||
break;
|
||||
case blink::WebMouseEvent::Button::X2:
|
||||
case blink::WebMouseEvent::Button::kForward:
|
||||
button_flags |= ui::EventFlags::EF_FORWARD_MOUSE_BUTTON;
|
||||
break;
|
||||
case blink::WebMouseEvent::Button::Left:
|
||||
case blink::WebMouseEvent::Button::kLeft:
|
||||
button_flags |= ui::EventFlags::EF_LEFT_MOUSE_BUTTON;
|
||||
break;
|
||||
case blink::WebMouseEvent::Button::Middle:
|
||||
case blink::WebMouseEvent::Button::kMiddle:
|
||||
button_flags |= ui::EventFlags::EF_MIDDLE_MOUSE_BUTTON;
|
||||
break;
|
||||
case blink::WebMouseEvent::Button::Right:
|
||||
case blink::WebMouseEvent::Button::kRight:
|
||||
button_flags |= ui::EventFlags::EF_RIGHT_MOUSE_BUTTON;
|
||||
break;
|
||||
default:
|
||||
@@ -90,11 +92,12 @@ ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
||||
}
|
||||
|
||||
ui::MouseEvent ui_event(type,
|
||||
gfx::Point(std::floor(event.x), std::floor(event.y)),
|
||||
gfx::Point(std::floor(event.x), std::floor(event.y)),
|
||||
ui::EventTimeForNow(),
|
||||
button_flags, button_flags);
|
||||
ui_event.SetClickCount(event.clickCount);
|
||||
gfx::Point(std::floor(event.PositionInWidget().x),
|
||||
std::floor(event.PositionInWidget().y)),
|
||||
gfx::Point(std::floor(event.PositionInWidget().x),
|
||||
std::floor(event.PositionInWidget().y)),
|
||||
ui::EventTimeForNow(), button_flags, button_flags);
|
||||
ui_event.SetClickCount(event.click_count);
|
||||
|
||||
return ui_event;
|
||||
}
|
||||
@@ -102,69 +105,9 @@ ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
||||
ui::MouseWheelEvent UiMouseWheelEventFromWebMouseEvent(
|
||||
blink::WebMouseWheelEvent event) {
|
||||
return ui::MouseWheelEvent(UiMouseEventFromWebMouseEvent(event),
|
||||
std::floor(event.deltaX), std::floor(event.deltaY));
|
||||
std::floor(event.delta_x), std::floor(event.delta_y));
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
|
||||
const int kResizeLockTimeoutMs = 67;
|
||||
|
||||
class AtomResizeLock : public content::ResizeLock {
|
||||
public:
|
||||
AtomResizeLock(OffScreenRenderWidgetHostView* host,
|
||||
const gfx::Size new_size,
|
||||
bool defer_compositor_lock)
|
||||
: ResizeLock(new_size, defer_compositor_lock),
|
||||
host_(host),
|
||||
cancelled_(false),
|
||||
weak_ptr_factory_(this) {
|
||||
DCHECK(host_);
|
||||
host_->HoldResize();
|
||||
|
||||
content::BrowserThread::PostDelayedTask(content::BrowserThread::UI,
|
||||
FROM_HERE, base::Bind(&AtomResizeLock::CancelLock,
|
||||
weak_ptr_factory_.GetWeakPtr()),
|
||||
base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs));
|
||||
}
|
||||
|
||||
~AtomResizeLock() override {
|
||||
CancelLock();
|
||||
}
|
||||
|
||||
bool GrabDeferredLock() override {
|
||||
return ResizeLock::GrabDeferredLock();
|
||||
}
|
||||
|
||||
void UnlockCompositor() override {
|
||||
ResizeLock::UnlockCompositor();
|
||||
compositor_lock_ = NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
void LockCompositor() override {
|
||||
ResizeLock::LockCompositor();
|
||||
compositor_lock_ = host_->GetCompositor()->GetCompositorLock();
|
||||
}
|
||||
|
||||
void CancelLock() {
|
||||
if (cancelled_)
|
||||
return;
|
||||
cancelled_ = true;
|
||||
UnlockCompositor();
|
||||
host_->ReleaseResize();
|
||||
}
|
||||
|
||||
private:
|
||||
OffScreenRenderWidgetHostView* host_;
|
||||
scoped_refptr<ui::CompositorLock> compositor_lock_;
|
||||
bool cancelled_;
|
||||
base::WeakPtrFactory<AtomResizeLock> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomResizeLock);
|
||||
};
|
||||
|
||||
#endif // !defined(OS_MACOSX)
|
||||
|
||||
} // namespace
|
||||
|
||||
class AtomCopyFrameGenerator {
|
||||
@@ -336,6 +279,8 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
popup_position_(gfx::Rect()),
|
||||
hold_resize_(false),
|
||||
pending_resize_(false),
|
||||
renderer_compositor_frame_sink_(nullptr),
|
||||
background_color_(SkColor()),
|
||||
weak_ptr_factory_(this) {
|
||||
DCHECK(render_widget_host_);
|
||||
bool is_guest_view_hack = parent_host_view_ != nullptr;
|
||||
@@ -554,14 +499,18 @@ gfx::Rect OffScreenRenderWidgetHostView::GetViewBounds() const {
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetBackgroundColor(SkColor color) {
|
||||
if (transparent_)
|
||||
color = SkColorSetARGB(SK_AlphaTRANSPARENT, 0, 0, 0);
|
||||
// The renderer will feed its color back to us with the first CompositorFrame.
|
||||
// We short-cut here to show a sensible color before that happens.
|
||||
UpdateBackgroundColorFromRenderer(color);
|
||||
|
||||
content::RenderWidgetHostViewBase::SetBackgroundColor(color);
|
||||
if (render_widget_host_) {
|
||||
render_widget_host_->SetBackgroundOpaque(SkColorGetA(color) ==
|
||||
SK_AlphaOPAQUE);
|
||||
}
|
||||
}
|
||||
|
||||
const bool opaque = !transparent_ && GetBackgroundOpaque();
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->SetBackgroundOpaque(opaque);
|
||||
SkColor OffScreenRenderWidgetHostView::background_color() const {
|
||||
return background_color_;
|
||||
}
|
||||
|
||||
gfx::Size OffScreenRenderWidgetHostView::GetVisibleViewportSize() const {
|
||||
@@ -578,11 +527,20 @@ bool OffScreenRenderWidgetHostView::LockMouse() {
|
||||
void OffScreenRenderWidgetHostView::UnlockMouse() {
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnSwapCompositorFrame(
|
||||
uint32_t output_surface_id,
|
||||
cc::CompositorFrame frame) {
|
||||
void OffScreenRenderWidgetHostView::DidCreateNewRendererCompositorFrameSink(
|
||||
cc::mojom::MojoCompositorFrameSinkClient* renderer_compositor_frame_sink) {
|
||||
renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
|
||||
if (GetDelegatedFrameHost()) {
|
||||
GetDelegatedFrameHost()->DidCreateNewRendererCompositorFrameSink(
|
||||
renderer_compositor_frame_sink_);
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
|
||||
const cc::LocalSurfaceId& local_surface_id,
|
||||
cc::CompositorFrame frame) {
|
||||
TRACE_EVENT0("electron",
|
||||
"OffScreenRenderWidgetHostView::OnSwapCompositorFrame");
|
||||
"OffScreenRenderWidgetHostView::SubmitCompositorFrame");
|
||||
|
||||
if (frame.metadata.root_scroll_offset != last_scroll_offset_) {
|
||||
last_scroll_offset_ = frame.metadata.root_scroll_offset;
|
||||
@@ -596,11 +554,11 @@ void OffScreenRenderWidgetHostView::OnSwapCompositorFrame(
|
||||
|
||||
// The compositor will draw directly to the SoftwareOutputDevice which
|
||||
// then calls OnPaint.
|
||||
// We would normally call BrowserCompositorMac::SwapCompositorFrame on
|
||||
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
|
||||
// macOS, however it contains compositor resize logic that we don't want.
|
||||
// Consequently we instead call the SwapDelegatedFrame method directly.
|
||||
GetDelegatedFrameHost()->SwapDelegatedFrame(output_surface_id,
|
||||
std::move(frame));
|
||||
// Consequently we instead call the SubmitCompositorFrame method directly.
|
||||
GetDelegatedFrameHost()->SubmitCompositorFrame(local_surface_id,
|
||||
std::move(frame));
|
||||
} else {
|
||||
if (!copy_frame_generator_.get()) {
|
||||
copy_frame_generator_.reset(
|
||||
@@ -615,11 +573,11 @@ void OffScreenRenderWidgetHostView::OnSwapCompositorFrame(
|
||||
gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect));
|
||||
damage_rect.Intersect(gfx::Rect(frame_size));
|
||||
|
||||
// We would normally call BrowserCompositorMac::SwapCompositorFrame on
|
||||
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
|
||||
// macOS, however it contains compositor resize logic that we don't want.
|
||||
// Consequently we instead call the SwapDelegatedFrame method directly.
|
||||
GetDelegatedFrameHost()->SwapDelegatedFrame(output_surface_id,
|
||||
std::move(frame));
|
||||
// Consequently we instead call the SubmitCompositorFrame method directly.
|
||||
GetDelegatedFrameHost()->SubmitCompositorFrame(local_surface_id,
|
||||
std::move(frame));
|
||||
|
||||
// Request a copy of the last compositor frame which will eventually call
|
||||
// OnPaint asynchronously.
|
||||
@@ -685,8 +643,14 @@ void OffScreenRenderWidgetHostView::Destroy() {
|
||||
popup_bitmap_.reset();
|
||||
if (child_host_view_)
|
||||
child_host_view_->CancelWidget();
|
||||
for (auto guest_host_view : guest_host_views_)
|
||||
guest_host_view->CancelWidget();
|
||||
if (!guest_host_views_.empty()) {
|
||||
// Guest RWHVs will be destroyed when the associated RWHVGuest is
|
||||
// destroyed. This parent RWHV may be destroyed first, so disassociate
|
||||
// the guest RWHVs here without destroying them.
|
||||
for (auto guest_host_view : guest_host_views_)
|
||||
guest_host_view->parent_host_view_ = nullptr;
|
||||
guest_host_views_.clear();
|
||||
}
|
||||
for (auto proxy_view : proxy_views_)
|
||||
proxy_view->RemoveObserver();
|
||||
Hide();
|
||||
@@ -807,31 +771,25 @@ bool OffScreenRenderWidgetHostView::DelegatedFrameCanCreateResizeLock() const {
|
||||
return !render_widget_host_->auto_resize_enabled();
|
||||
}
|
||||
|
||||
std::unique_ptr<content::ResizeLock>
|
||||
OffScreenRenderWidgetHostView::DelegatedFrameHostCreateResizeLock(
|
||||
bool defer_compositor_lock) {
|
||||
return std::unique_ptr<content::ResizeLock>(new AtomResizeLock(
|
||||
this,
|
||||
DelegatedFrameHostDesiredSizeInDIP(),
|
||||
defer_compositor_lock));
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::DelegatedFrameHostResizeLockWasReleased() {
|
||||
return render_widget_host_->WasResized();
|
||||
std::unique_ptr<content::CompositorResizeLock>
|
||||
OffScreenRenderWidgetHostView::DelegatedFrameHostCreateResizeLock() {
|
||||
HoldResize();
|
||||
const gfx::Size& desired_size = GetRootLayer()->bounds().size();
|
||||
return base::MakeUnique<content::CompositorResizeLock>(this, desired_size);
|
||||
}
|
||||
|
||||
void
|
||||
OffScreenRenderWidgetHostView::DelegatedFrameHostSendReclaimCompositorResources(
|
||||
int output_surface_id,
|
||||
bool is_swap_ack,
|
||||
const cc::ReturnedResourceArray& resources) {
|
||||
render_widget_host_->Send(new ViewMsg_ReclaimCompositorResources(
|
||||
render_widget_host_->GetRoutingID(), output_surface_id, is_swap_ack,
|
||||
resources));
|
||||
OffScreenRenderWidgetHostView::OnBeginFrame(const cc::BeginFrameArgs& args) {
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetBeginFrameSource(
|
||||
cc::BeginFrameSource* source) {
|
||||
std::unique_ptr<ui::CompositorLock>
|
||||
OffScreenRenderWidgetHostView::GetCompositorLock(
|
||||
ui::CompositorLockClient* client) {
|
||||
return GetCompositor()->GetCompositorLock(client);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::CompositorResizeLockEnded() {
|
||||
ReleaseResize();
|
||||
}
|
||||
|
||||
#endif // !defined(OS_MACOSX)
|
||||
@@ -1111,12 +1069,12 @@ void OffScreenRenderWidgetHostView::ProcessMouseEvent(
|
||||
const ui::LatencyInfo& latency) {
|
||||
for (auto proxy_view : proxy_views_) {
|
||||
gfx::Rect bounds = proxy_view->GetBounds();
|
||||
if (bounds.Contains(event.x, event.y)) {
|
||||
if (bounds.Contains(event.PositionInWidget().x,
|
||||
event.PositionInWidget().y)) {
|
||||
blink::WebMouseEvent proxy_event(event);
|
||||
proxy_event.x -= bounds.x();
|
||||
proxy_event.y -= bounds.y();
|
||||
proxy_event.windowX = proxy_event.x;
|
||||
proxy_event.windowY = proxy_event.y;
|
||||
proxy_event.SetPositionInWidget(
|
||||
proxy_event.PositionInWidget().x - bounds.x(),
|
||||
proxy_event.PositionInWidget().y - bounds.y());
|
||||
|
||||
ui::MouseEvent ui_event = UiMouseEventFromWebMouseEvent(proxy_event);
|
||||
proxy_view->OnEvent(&ui_event);
|
||||
@@ -1125,13 +1083,14 @@ void OffScreenRenderWidgetHostView::ProcessMouseEvent(
|
||||
}
|
||||
|
||||
if (!IsPopupWidget()) {
|
||||
if (popup_host_view_ &&
|
||||
popup_host_view_->popup_position_.Contains(event.x, event.y)) {
|
||||
if (popup_host_view_ && popup_host_view_->popup_position_.Contains(
|
||||
event.PositionInWidget().x, event.PositionInWidget().y)) {
|
||||
blink::WebMouseEvent popup_event(event);
|
||||
popup_event.x -= popup_host_view_->popup_position_.x();
|
||||
popup_event.y -= popup_host_view_->popup_position_.y();
|
||||
popup_event.windowX = popup_event.x;
|
||||
popup_event.windowY = popup_event.y;
|
||||
popup_event.SetPositionInWidget(
|
||||
popup_event.PositionInWidget().x -
|
||||
popup_host_view_->popup_position_.x(),
|
||||
popup_event.PositionInWidget().y -
|
||||
popup_host_view_->popup_position_.y());
|
||||
|
||||
popup_host_view_->ProcessMouseEvent(popup_event, latency);
|
||||
return;
|
||||
@@ -1148,12 +1107,12 @@ void OffScreenRenderWidgetHostView::ProcessMouseWheelEvent(
|
||||
const ui::LatencyInfo& latency) {
|
||||
for (auto proxy_view : proxy_views_) {
|
||||
gfx::Rect bounds = proxy_view->GetBounds();
|
||||
if (bounds.Contains(event.x, event.y)) {
|
||||
if (bounds.Contains(event.PositionInWidget().x,
|
||||
event.PositionInWidget().y)) {
|
||||
blink::WebMouseWheelEvent proxy_event(event);
|
||||
proxy_event.x -= bounds.x();
|
||||
proxy_event.y -= bounds.y();
|
||||
proxy_event.windowX = proxy_event.x;
|
||||
proxy_event.windowY = proxy_event.y;
|
||||
proxy_event.SetPositionInWidget(
|
||||
proxy_event.PositionInWidget().x - bounds.x(),
|
||||
proxy_event.PositionInWidget().y - bounds.y());
|
||||
|
||||
ui::MouseWheelEvent ui_event =
|
||||
UiMouseWheelEventFromWebMouseEvent(proxy_event);
|
||||
@@ -1163,12 +1122,14 @@ void OffScreenRenderWidgetHostView::ProcessMouseWheelEvent(
|
||||
}
|
||||
if (!IsPopupWidget()) {
|
||||
if (popup_host_view_) {
|
||||
if (popup_host_view_->popup_position_.Contains(event.x, event.y)) {
|
||||
if (popup_host_view_->popup_position_.Contains(
|
||||
event.PositionInWidget().x, event.PositionInWidget().y)) {
|
||||
blink::WebMouseWheelEvent popup_event(event);
|
||||
popup_event.x -= popup_host_view_->popup_position_.x();
|
||||
popup_event.y -= popup_host_view_->popup_position_.y();
|
||||
popup_event.windowX = popup_event.x;
|
||||
popup_event.windowY = popup_event.y;
|
||||
popup_event.SetPositionInWidget(
|
||||
popup_event.PositionInWidget().x -
|
||||
popup_host_view_->popup_position_.x(),
|
||||
popup_event.PositionInWidget().y -
|
||||
popup_host_view_->popup_position_.y());
|
||||
popup_host_view_->ProcessMouseWheelEvent(popup_event, latency);
|
||||
return;
|
||||
} else {
|
||||
@@ -1312,4 +1273,15 @@ cc::FrameSinkId OffScreenRenderWidgetHostView::AllocateFrameSinkId(
|
||||
render_widget_host_->GetRoutingID()));
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::UpdateBackgroundColorFromRenderer(
|
||||
SkColor color) {
|
||||
if (color == background_color())
|
||||
return;
|
||||
background_color_ = color;
|
||||
|
||||
bool opaque = SkColorGetA(color) == SK_AlphaOPAQUE;
|
||||
GetRootLayer()->SetFillsBoundsOpaquely(opaque);
|
||||
GetRootLayer()->SetColor(color);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
#include "cc/output/compositor_frame.h"
|
||||
#include "cc/scheduler/begin_frame_source.h"
|
||||
#include "content/browser/frame_host/render_widget_host_view_guest.h"
|
||||
#include "content/browser/renderer_host/compositor_resize_lock.h"
|
||||
#include "content/browser/renderer_host/delegated_frame_host.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_base.h"
|
||||
#include "content/browser/renderer_host/resize_lock.h"
|
||||
#include "content/browser/web_contents/web_contents_view.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "third_party/WebKit/public/platform/WebVector.h"
|
||||
@@ -68,6 +68,7 @@ class OffScreenRenderWidgetHostView
|
||||
public ui::CompositorDelegate,
|
||||
#if !defined(OS_MACOSX)
|
||||
public content::DelegatedFrameHostClient,
|
||||
public content::CompositorResizeLockClient,
|
||||
#endif
|
||||
public NativeWindowObserver,
|
||||
public OffscreenViewProxyObserver {
|
||||
@@ -99,6 +100,7 @@ class OffScreenRenderWidgetHostView
|
||||
gfx::Size GetVisibleViewportSize() const override;
|
||||
void SetInsets(const gfx::Insets&) override;
|
||||
void SetBackgroundColor(SkColor color) override;
|
||||
SkColor background_color() const override;
|
||||
bool LockMouse(void) override;
|
||||
void UnlockMouse(void) override;
|
||||
void SetNeedsBeginFrames(bool needs_begin_frames) override;
|
||||
@@ -113,8 +115,12 @@ class OffScreenRenderWidgetHostView
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
// content::RenderWidgetHostViewBase:
|
||||
void OnSwapCompositorFrame(uint32_t, cc::CompositorFrame)
|
||||
override;
|
||||
void DidCreateNewRendererCompositorFrameSink(
|
||||
cc::mojom::MojoCompositorFrameSinkClient* renderer_compositor_frame_sink)
|
||||
override;
|
||||
void SubmitCompositorFrame(const cc::LocalSurfaceId& local_surface_id,
|
||||
cc::CompositorFrame frame) override;
|
||||
|
||||
void ClearCompositorFrame(void) override;
|
||||
void InitAsPopup(content::RenderWidgetHostView *rwhv, const gfx::Rect& rect)
|
||||
override;
|
||||
@@ -167,15 +173,14 @@ class OffScreenRenderWidgetHostView
|
||||
bool DelegatedFrameHostIsVisible(void) const override;
|
||||
SkColor DelegatedFrameHostGetGutterColor(SkColor) const override;
|
||||
gfx::Size DelegatedFrameHostDesiredSizeInDIP(void) const override;
|
||||
bool DelegatedFrameCanCreateResizeLock(void) const override;
|
||||
std::unique_ptr<content::ResizeLock> DelegatedFrameHostCreateResizeLock(
|
||||
bool defer_compositor_lock) override;
|
||||
void DelegatedFrameHostResizeLockWasReleased(void) override;
|
||||
void DelegatedFrameHostSendReclaimCompositorResources(
|
||||
int output_surface_id,
|
||||
bool is_swap_ack,
|
||||
const cc::ReturnedResourceArray& resources) override;
|
||||
void SetBeginFrameSource(cc::BeginFrameSource* source) override;
|
||||
bool DelegatedFrameCanCreateResizeLock() const override;
|
||||
std::unique_ptr<content::CompositorResizeLock>
|
||||
DelegatedFrameHostCreateResizeLock() override;
|
||||
void OnBeginFrame(const cc::BeginFrameArgs& args) override;
|
||||
// CompositorResizeLockClient implementation.
|
||||
std::unique_ptr<ui::CompositorLock> GetCompositorLock(
|
||||
ui::CompositorLockClient* client) override;
|
||||
void CompositorResizeLockEnded() override;
|
||||
#endif // !defined(OS_MACOSX)
|
||||
|
||||
bool TransformPointToLocalCoordSpace(
|
||||
@@ -224,7 +229,7 @@ class OffScreenRenderWidgetHostView
|
||||
void OnProxyViewPaint(const gfx::Rect& damage_rect);
|
||||
|
||||
bool IsPopupWidget() const {
|
||||
return popup_type_ != blink::WebPopupTypeNone;
|
||||
return popup_type_ != blink::kWebPopupTypeNone;
|
||||
}
|
||||
|
||||
void HoldResize();
|
||||
@@ -271,6 +276,10 @@ class OffScreenRenderWidgetHostView
|
||||
|
||||
cc::FrameSinkId AllocateFrameSinkId(bool is_guest_view_hack);
|
||||
|
||||
// Applies background color without notifying the RenderWidget about
|
||||
// opaqueness changes.
|
||||
void UpdateBackgroundColorFromRenderer(SkColor color);
|
||||
|
||||
// Weak ptrs.
|
||||
content::RenderWidgetHostImpl* render_widget_host_;
|
||||
|
||||
@@ -328,6 +337,10 @@ class OffScreenRenderWidgetHostView
|
||||
std::string selected_text_;
|
||||
#endif
|
||||
|
||||
cc::mojom::MojoCompositorFrameSinkClient* renderer_compositor_frame_sink_;
|
||||
|
||||
SkColor background_color_;
|
||||
|
||||
base::WeakPtrFactory<OffScreenRenderWidgetHostView> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(OffScreenRenderWidgetHostView);
|
||||
|
||||
@@ -38,15 +38,6 @@ class MacHelper :
|
||||
return color;
|
||||
}
|
||||
|
||||
void BrowserCompositorMacSendReclaimCompositorResources(
|
||||
int output_surface_id,
|
||||
bool is_swap_ack,
|
||||
const cc::ReturnedResourceArray& resources) override {
|
||||
view_->render_widget_host()->Send(new ViewMsg_ReclaimCompositorResources(
|
||||
view_->render_widget_host()->GetRoutingID(), output_surface_id,
|
||||
is_swap_ack, resources));
|
||||
}
|
||||
|
||||
void BrowserCompositorMacSendBeginFrame(
|
||||
const cc::BeginFrameArgs& args) override {
|
||||
view_->render_widget_host()->Send(
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.7.8</string>
|
||||
<string>1.8.2</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.7.8</string>
|
||||
<string>1.8.2</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -56,8 +56,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,7,8,0
|
||||
PRODUCTVERSION 1,7,8,0
|
||||
FILEVERSION 1,8,2,1
|
||||
PRODUCTVERSION 1,8,2,1
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -74,12 +74,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "1.7.8"
|
||||
VALUE "FileVersion", "1.8.2"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "1.7.8"
|
||||
VALUE "ProductVersion", "1.8.2"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "net/cert/cert_database.h"
|
||||
#include "net/cert/x509_util_mac.h"
|
||||
|
||||
@interface TrustDelegate : NSObject {
|
||||
@private
|
||||
@@ -85,7 +86,8 @@ void ShowCertificateTrust(atom::NativeWindow* parent_window,
|
||||
const std::string& message,
|
||||
const ShowTrustCallback& callback) {
|
||||
auto sec_policy = SecPolicyCreateBasicX509();
|
||||
auto cert_chain = cert->CreateOSCertChainForCert();
|
||||
auto cert_chain =
|
||||
net::x509_util::CreateSecCertificateArrayForX509Certificate(cert.get());
|
||||
SecTrustRef trust = nullptr;
|
||||
SecTrustCreateWithCertificates(cert_chain, sec_policy, &trust);
|
||||
|
||||
|
||||
42
atom/browser/ui/cocoa/atom_bundle_mover.h
Normal file
42
atom/browser/ui/cocoa/atom_bundle_mover.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_COCOA_ATOM_BUNDLE_MOVER_H_
|
||||
#define ATOM_BROWSER_UI_COCOA_ATOM_BUNDLE_MOVER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "native_mate/persistent_dictionary.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace ui {
|
||||
|
||||
namespace cocoa {
|
||||
|
||||
class AtomBundleMover {
|
||||
public:
|
||||
static bool Move(mate::Arguments* args);
|
||||
static bool IsCurrentAppInApplicationsFolder();
|
||||
|
||||
private:
|
||||
static bool IsInApplicationsFolder(NSString* bundlePath);
|
||||
static NSString* ContainingDiskImageDevice(NSString* bundlePath);
|
||||
static void Relaunch(NSString* destinationPath);
|
||||
static NSString* ShellQuotedString(NSString* string);
|
||||
static bool CopyBundle(NSString* srcPath, NSString* dstPath);
|
||||
static bool AuthorizedInstall(NSString* srcPath, NSString* dstPath,
|
||||
bool* canceled);
|
||||
static bool IsApplicationAtPathRunning(NSString* bundlePath);
|
||||
static bool DeleteOrTrash(NSString* path);
|
||||
static bool Trash(NSString* path);
|
||||
};
|
||||
|
||||
} // namespace cocoa
|
||||
|
||||
} // namespace ui
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_COCOA_ATOM_BUNDLE_MOVER_H_
|
||||
345
atom/browser/ui/cocoa/atom_bundle_mover.mm
Normal file
345
atom/browser/ui/cocoa/atom_bundle_mover.mm
Normal file
@@ -0,0 +1,345 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "atom/browser/ui/cocoa/atom_bundle_mover.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Security/Security.h>
|
||||
#import <dlfcn.h>
|
||||
#import <sys/param.h>
|
||||
#import <sys/mount.h>
|
||||
|
||||
#import "atom/browser/browser.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace ui {
|
||||
|
||||
namespace cocoa {
|
||||
|
||||
bool AtomBundleMover::Move(mate::Arguments* args) {
|
||||
// Path of the current bundle
|
||||
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
|
||||
|
||||
// Skip if the application is already in the Applications folder
|
||||
if (IsInApplicationsFolder(bundlePath)) return true;
|
||||
|
||||
NSFileManager* fileManager = [NSFileManager defaultManager];
|
||||
|
||||
NSString* diskImageDevice = ContainingDiskImageDevice(bundlePath);
|
||||
|
||||
NSString *applicationsDirectory = [[NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSLocalDomainMask, true) lastObject] stringByResolvingSymlinksInPath];
|
||||
NSString *bundleName = [bundlePath lastPathComponent];
|
||||
NSString *destinationPath = [applicationsDirectory stringByAppendingPathComponent:bundleName];
|
||||
|
||||
// Check if we can write to the applications directory
|
||||
// and then make sure that if the app already exists we can overwrite it
|
||||
bool needAuthorization = ![fileManager isWritableFileAtPath:applicationsDirectory]
|
||||
| ([fileManager fileExistsAtPath:destinationPath] && ![fileManager isWritableFileAtPath:destinationPath]);
|
||||
|
||||
// Activate app -- work-around for focus issues related to "scary file from internet" OS dialog.
|
||||
if (![NSApp isActive]) {
|
||||
[NSApp activateIgnoringOtherApps:true];
|
||||
}
|
||||
|
||||
// Move to applications folder
|
||||
if (needAuthorization) {
|
||||
bool authorizationCanceled;
|
||||
|
||||
if (!AuthorizedInstall(bundlePath, destinationPath, &authorizationCanceled)) {
|
||||
if (authorizationCanceled) {
|
||||
// User rejected the authorization request
|
||||
args->ThrowError("User rejected the authorization request");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
args->ThrowError("Failed to copy to applications directory even with authorization");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If a copy already exists in the Applications folder, put it in the Trash
|
||||
if ([fileManager fileExistsAtPath:destinationPath]) {
|
||||
// But first, make sure that it's not running
|
||||
if (IsApplicationAtPathRunning(destinationPath)) {
|
||||
// Give the running app focus and terminate myself
|
||||
[[NSTask launchedTaskWithLaunchPath:@"/usr/bin/open" arguments:[NSArray arrayWithObject:destinationPath]] waitUntilExit];
|
||||
atom::Browser::Get()->Quit();
|
||||
return true;
|
||||
} else {
|
||||
if (!Trash([applicationsDirectory stringByAppendingPathComponent:bundleName])) {
|
||||
args->ThrowError("Failed to delete existing application");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!CopyBundle(bundlePath, destinationPath)) {
|
||||
args->ThrowError("Failed to copy current bundle to the applications folder");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Trash the original app. It's okay if this fails.
|
||||
// NOTE: This final delete does not work if the source bundle is in a network mounted volume.
|
||||
// Calling rm or file manager's delete method doesn't work either. It's unlikely to happen
|
||||
// but it'd be great if someone could fix this.
|
||||
if (diskImageDevice == nil && !DeleteOrTrash(bundlePath)) {
|
||||
// Could not delete original but we just don't care
|
||||
}
|
||||
|
||||
// Relaunch.
|
||||
Relaunch(destinationPath);
|
||||
|
||||
// Launched from within a disk image? -- unmount (if no files are open after 5 seconds,
|
||||
// otherwise leave it mounted).
|
||||
if (diskImageDevice) {
|
||||
NSString *script = [NSString stringWithFormat:@"(/bin/sleep 5 && /usr/bin/hdiutil detach %@) &", ShellQuotedString(diskImageDevice)];
|
||||
[NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", script, nil]];
|
||||
}
|
||||
|
||||
atom::Browser::Get()->Quit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtomBundleMover::IsCurrentAppInApplicationsFolder() {
|
||||
return IsInApplicationsFolder([[NSBundle mainBundle] bundlePath]);
|
||||
}
|
||||
|
||||
bool AtomBundleMover::IsInApplicationsFolder(NSString* bundlePath) {
|
||||
// Check all the normal Application directories
|
||||
NSArray* applicationDirs = NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSAllDomainsMask, true);
|
||||
for (NSString* appDir in applicationDirs) {
|
||||
if ([bundlePath hasPrefix:appDir]) return true;
|
||||
}
|
||||
|
||||
// Also, handle the case that the user has some other Application directory (perhaps on a separate data partition).
|
||||
if ([[bundlePath pathComponents] containsObject:@"Applications"]) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
NSString* AtomBundleMover::ContainingDiskImageDevice(NSString* bundlePath) {
|
||||
NSString* containingPath = [bundlePath stringByDeletingLastPathComponent];
|
||||
|
||||
struct statfs fs;
|
||||
if (statfs([containingPath fileSystemRepresentation], &fs) || (fs.f_flags & MNT_ROOTFS))
|
||||
return nil;
|
||||
|
||||
NSString *device = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:fs.f_mntfromname length:strlen(fs.f_mntfromname)];
|
||||
|
||||
NSTask *hdiutil = [[[NSTask alloc] init] autorelease];
|
||||
[hdiutil setLaunchPath:@"/usr/bin/hdiutil"];
|
||||
[hdiutil setArguments:[NSArray arrayWithObjects:@"info", @"-plist", nil]];
|
||||
[hdiutil setStandardOutput:[NSPipe pipe]];
|
||||
[hdiutil launch];
|
||||
[hdiutil waitUntilExit];
|
||||
|
||||
NSData *data = [[[hdiutil standardOutput] fileHandleForReading] readDataToEndOfFile];
|
||||
|
||||
NSDictionary *info = nil;
|
||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) {
|
||||
info = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:NULL error:NULL];
|
||||
} else {
|
||||
info = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListImmutable format:NULL errorDescription:NULL];
|
||||
}
|
||||
|
||||
if (![info isKindOfClass:[NSDictionary class]]) return nil;
|
||||
|
||||
NSArray *images = (NSArray *)[info objectForKey:@"images"];
|
||||
if (![images isKindOfClass:[NSArray class]]) return nil;
|
||||
|
||||
for (NSDictionary *image in images) {
|
||||
if (![image isKindOfClass:[NSDictionary class]]) return nil;
|
||||
|
||||
id systemEntities = [image objectForKey:@"system-entities"];
|
||||
if (![systemEntities isKindOfClass:[NSArray class]]) return nil;
|
||||
|
||||
for (NSDictionary *systemEntity in systemEntities) {
|
||||
if (![systemEntity isKindOfClass:[NSDictionary class]]) return nil;
|
||||
|
||||
NSString *devEntry = [systemEntity objectForKey:@"dev-entry"];
|
||||
if (![devEntry isKindOfClass:[NSString class]]) return nil;
|
||||
|
||||
if ([devEntry isEqualToString:device])
|
||||
return device;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
bool AtomBundleMover::AuthorizedInstall(NSString* srcPath, NSString* dstPath, bool* canceled) {
|
||||
if (canceled) *canceled = false;
|
||||
|
||||
// Make sure that the destination path is an app bundle. We're essentially running 'sudo rm -rf'
|
||||
// so we really don't want to screw this up.
|
||||
if (![[dstPath pathExtension] isEqualToString:@"app"]) return false;
|
||||
|
||||
// Do some more checks
|
||||
if ([[dstPath stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) return false;
|
||||
if ([[srcPath stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) return false;
|
||||
|
||||
int pid, status;
|
||||
AuthorizationRef myAuthorizationRef;
|
||||
|
||||
// Get the authorization
|
||||
OSStatus err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &myAuthorizationRef);
|
||||
if (err != errAuthorizationSuccess) return false;
|
||||
|
||||
AuthorizationItem myItems = {kAuthorizationRightExecute, 0, NULL, 0};
|
||||
AuthorizationRights myRights = {1, &myItems};
|
||||
AuthorizationFlags myFlags = (AuthorizationFlags)(kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize);
|
||||
|
||||
err = AuthorizationCopyRights(myAuthorizationRef, &myRights, NULL, myFlags, NULL);
|
||||
if (err != errAuthorizationSuccess) {
|
||||
if (err == errAuthorizationCanceled && canceled)
|
||||
*canceled = true;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
static OSStatus (*security_AuthorizationExecuteWithPrivileges)(AuthorizationRef authorization, const char *pathToTool,
|
||||
AuthorizationFlags options, char * const *arguments,
|
||||
FILE **communicationsPipe) = NULL;
|
||||
if (!security_AuthorizationExecuteWithPrivileges) {
|
||||
// On 10.7, AuthorizationExecuteWithPrivileges is deprecated. We want to still use it since there's no
|
||||
// good alternative (without requiring code signing). We'll look up the function through dyld and fail
|
||||
// if it is no longer accessible. If Apple removes the function entirely this will fail gracefully. If
|
||||
// they keep the function and throw some sort of exception, this won't fail gracefully, but that's a
|
||||
// risk we'll have to take for now.
|
||||
security_AuthorizationExecuteWithPrivileges = (OSStatus (*)(AuthorizationRef, const char*,
|
||||
AuthorizationFlags, char* const*,
|
||||
FILE **)) dlsym(RTLD_DEFAULT, "AuthorizationExecuteWithPrivileges");
|
||||
}
|
||||
if (!security_AuthorizationExecuteWithPrivileges) goto fail;
|
||||
|
||||
// Delete the destination
|
||||
{
|
||||
char rf[] = "-rf";
|
||||
char *args[] = {rf, (char *)[dstPath fileSystemRepresentation], NULL};
|
||||
err = security_AuthorizationExecuteWithPrivileges(myAuthorizationRef, "/bin/rm", kAuthorizationFlagDefaults, args, NULL);
|
||||
if (err != errAuthorizationSuccess) goto fail;
|
||||
|
||||
// Wait until it's done
|
||||
pid = wait(&status);
|
||||
if (pid == -1 || !WIFEXITED(status)) goto fail; // We don't care about exit status as the destination most likely does not exist
|
||||
}
|
||||
|
||||
// Copy
|
||||
{
|
||||
char pR[] = "-pR";
|
||||
char *args[] = {pR, (char *)[srcPath fileSystemRepresentation], (char *)[dstPath fileSystemRepresentation], NULL};
|
||||
err = security_AuthorizationExecuteWithPrivileges(myAuthorizationRef, "/bin/cp", kAuthorizationFlagDefaults, args, NULL);
|
||||
if (err != errAuthorizationSuccess) goto fail;
|
||||
|
||||
// Wait until it's done
|
||||
pid = wait(&status);
|
||||
if (pid == -1 || !WIFEXITED(status) || WEXITSTATUS(status)) goto fail;
|
||||
}
|
||||
|
||||
AuthorizationFree(myAuthorizationRef, kAuthorizationFlagDefaults);
|
||||
return true;
|
||||
|
||||
fail:
|
||||
AuthorizationFree(myAuthorizationRef, kAuthorizationFlagDefaults);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomBundleMover::CopyBundle(NSString* srcPath, NSString* dstPath) {
|
||||
NSFileManager* fileManager = [NSFileManager defaultManager];
|
||||
NSError* error = nil;
|
||||
|
||||
if ([fileManager copyItemAtPath:srcPath toPath:dstPath error:&error]) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
NSString* AtomBundleMover::ShellQuotedString(NSString* string) {
|
||||
return [NSString stringWithFormat:@"'%@'", [string stringByReplacingOccurrencesOfString:@"'" withString:@"'\\''"]];
|
||||
}
|
||||
|
||||
void AtomBundleMover::Relaunch(NSString* destinationPath) {
|
||||
// The shell script waits until the original app process terminates.
|
||||
// This is done so that the relaunched app opens as the front-most app.
|
||||
int pid = [[NSProcessInfo processInfo] processIdentifier];
|
||||
|
||||
// Command run just before running open /final/path
|
||||
NSString* preOpenCmd = @"";
|
||||
|
||||
NSString* quotedDestinationPath = ShellQuotedString(destinationPath);
|
||||
|
||||
// Before we launch the new app, clear xattr:com.apple.quarantine to avoid
|
||||
// duplicate "scary file from the internet" dialog.
|
||||
preOpenCmd = [NSString stringWithFormat:@"/usr/bin/xattr -d -r com.apple.quarantine %@", quotedDestinationPath];
|
||||
|
||||
NSString* script = [NSString stringWithFormat:@"(while /bin/kill -0 %d >&/dev/null; do /bin/sleep 0.1; done; %@; /usr/bin/open %@) &", pid, preOpenCmd, quotedDestinationPath];
|
||||
|
||||
[NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", script, nil]];
|
||||
}
|
||||
|
||||
bool AtomBundleMover::IsApplicationAtPathRunning(NSString* bundlePath) {
|
||||
bundlePath = [bundlePath stringByStandardizingPath];
|
||||
|
||||
for (NSRunningApplication *runningApplication in [[NSWorkspace sharedWorkspace] runningApplications]) {
|
||||
NSString* runningAppBundlePath = [[[runningApplication bundleURL] path] stringByStandardizingPath];
|
||||
if ([runningAppBundlePath isEqualToString:bundlePath]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomBundleMover::Trash(NSString* path) {
|
||||
bool result = false;
|
||||
|
||||
if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_8) {
|
||||
result = [[NSFileManager defaultManager] trashItemAtURL:[NSURL fileURLWithPath:path] resultingItemURL:NULL error:NULL];
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
result = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation
|
||||
source:[path stringByDeletingLastPathComponent]
|
||||
destination:@""
|
||||
files:[NSArray arrayWithObject:[path lastPathComponent]]
|
||||
tag:NULL];
|
||||
}
|
||||
|
||||
// As a last resort try trashing with AppleScript.
|
||||
// This allows us to trash the app in macOS Sierra even when the app is running inside
|
||||
// an app translocation image.
|
||||
if (!result) {
|
||||
NSAppleScript* appleScript = [[[NSAppleScript alloc] initWithSource:
|
||||
[NSString stringWithFormat:@"\
|
||||
set theFile to POSIX file \"%@\" \n\
|
||||
tell application \"Finder\" \n\
|
||||
move theFile to trash \n\
|
||||
end tell", path]] autorelease];
|
||||
NSDictionary* errorDict = nil;
|
||||
NSAppleEventDescriptor* scriptResult = [appleScript executeAndReturnError:&errorDict];
|
||||
result = (scriptResult != nil);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AtomBundleMover::DeleteOrTrash(NSString* path) {
|
||||
NSError* error;
|
||||
|
||||
if ([[NSFileManager defaultManager] removeItemAtPath:path error:&error]) {
|
||||
return true;
|
||||
} else {
|
||||
return Trash(path);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cocoa
|
||||
|
||||
} // namespace ui
|
||||
|
||||
} // namespace atom
|
||||
@@ -45,6 +45,11 @@ Role kRolesMap[] = {
|
||||
{ @selector(performZoom:), "zoom" },
|
||||
{ @selector(terminate:), "quit" },
|
||||
{ @selector(toggleFullScreen:), "togglefullscreen" },
|
||||
{ @selector(toggleTabBar:), "toggletabbar" },
|
||||
{ @selector(selectNextTab:), "selectnexttab" },
|
||||
{ @selector(selectPreviousTab:), "selectprevioustab" },
|
||||
{ @selector(mergeAllWindows:), "mergeallwindows" },
|
||||
{ @selector(moveTabToNewWindow:), "movetabtonewwindow" },
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -143,6 +143,7 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
|
||||
}
|
||||
|
||||
- (void)setEscapeTouchBarItem:(const mate::PersistentDictionary&)item forTouchBar:(NSTouchBar*)touchBar {
|
||||
if (![touchBar respondsToSelector:@selector(escapeKeyReplacementItemIdentifier)]) return;
|
||||
std::string type;
|
||||
std::string item_id;
|
||||
NSTouchBarItemIdentifier identifier = nil;
|
||||
|
||||
@@ -7,12 +7,13 @@
|
||||
#include "ui/aura/client/drag_drop_client.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/base/dragdrop/drag_drop_types.h"
|
||||
#include "ui/base/dragdrop/drag_utils.h"
|
||||
#include "ui/base/dragdrop/file_info.h"
|
||||
#include "ui/base/dragdrop/os_exchange_data.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
#include "ui/views/button_drag_utils.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -22,7 +23,9 @@ void DragFileItems(const std::vector<base::FilePath>& files,
|
||||
// Set up our OLE machinery
|
||||
ui::OSExchangeData data;
|
||||
|
||||
drag_utils::CreateDragImageForFile(files[0], icon.AsImageSkia(), &data);
|
||||
button_drag_utils::SetDragImage(GURL(), files[0].LossyDisplayName(),
|
||||
icon.AsImageSkia(), nullptr,
|
||||
*views::Widget::GetTopLevelWidgetForNativeView(view), &data);
|
||||
|
||||
std::vector<ui::FileInfo> file_infos;
|
||||
for (const base::FilePath& file : files) {
|
||||
|
||||
@@ -34,9 +34,11 @@ gfx::Rect TrayIcon::GetBounds() {
|
||||
return gfx::Rect();
|
||||
}
|
||||
|
||||
void TrayIcon::NotifyClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
void TrayIcon::NotifyClicked(const gfx::Rect& bounds,
|
||||
const gfx::Point& location,
|
||||
int modifiers) {
|
||||
for (TrayIconObserver& observer : observers_)
|
||||
observer.OnClicked(bounds, modifiers);
|
||||
observer.OnClicked(bounds, location, modifiers);
|
||||
}
|
||||
|
||||
void TrayIcon::NotifyDoubleClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
@@ -89,6 +91,11 @@ void TrayIcon::NotifyMouseExited(const gfx::Point& location, int modifiers) {
|
||||
observer.OnMouseExited(location, modifiers);
|
||||
}
|
||||
|
||||
void TrayIcon::NotifyMouseMoved(const gfx::Point& location, int modifiers) {
|
||||
for (TrayIconObserver& observer : observers_)
|
||||
observer.OnMouseMoved(location, modifiers);
|
||||
}
|
||||
|
||||
void TrayIcon::NotifyDragEntered() {
|
||||
for (TrayIconObserver& observer : observers_)
|
||||
observer.OnDragEntered();
|
||||
|
||||
@@ -70,7 +70,9 @@ class TrayIcon {
|
||||
void AddObserver(TrayIconObserver* obs) { observers_.AddObserver(obs); }
|
||||
void RemoveObserver(TrayIconObserver* obs) { observers_.RemoveObserver(obs); }
|
||||
|
||||
void NotifyClicked(const gfx::Rect& = gfx::Rect(), int modifiers = 0);
|
||||
void NotifyClicked(const gfx::Rect& = gfx::Rect(),
|
||||
const gfx::Point& location = gfx::Point(),
|
||||
int modifiers = 0);
|
||||
void NotifyDoubleClicked(const gfx::Rect& = gfx::Rect(), int modifiers = 0);
|
||||
void NotifyBalloonShow();
|
||||
void NotifyBalloonClicked();
|
||||
@@ -87,6 +89,8 @@ class TrayIcon {
|
||||
int modifiers = 0);
|
||||
void NotifyMouseExited(const gfx::Point& location = gfx::Point(),
|
||||
int modifiers = 0);
|
||||
void NotifyMouseMoved(const gfx::Point& location = gfx::Point(),
|
||||
int modifiers = 0);
|
||||
|
||||
protected:
|
||||
TrayIcon();
|
||||
|
||||
@@ -57,10 +57,10 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
// Finalize setup by sizing our views
|
||||
[self updateDimensions];
|
||||
|
||||
// Add NSTrackingArea for listening to mouseEnter and mouseExit events
|
||||
// Add NSTrackingArea for listening to mouseEnter, mouseExit, and mouseMove events
|
||||
auto trackingArea = [[[NSTrackingArea alloc]
|
||||
initWithRect:[self bounds]
|
||||
options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways
|
||||
options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveAlways
|
||||
owner:self
|
||||
userInfo:nil] autorelease];
|
||||
[self addTrackingArea:trackingArea];
|
||||
@@ -249,6 +249,7 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
if (event.clickCount == 1)
|
||||
trayIcon_->NotifyClicked(
|
||||
gfx::ScreenRectFromNSRect(event.window.frame),
|
||||
gfx::ScreenPointFromNSPoint([event locationInWindow]),
|
||||
ui::EventFlagsFromModifiers([event modifierFlags]));
|
||||
|
||||
// Double click event.
|
||||
@@ -307,6 +308,12 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
ui::EventFlagsFromModifiers([event modifierFlags]));
|
||||
}
|
||||
|
||||
- (void)mouseMoved:(NSEvent*)event {
|
||||
trayIcon_->NotifyMouseMoved(
|
||||
gfx::ScreenPointFromNSPoint([event locationInWindow]),
|
||||
ui::EventFlagsFromModifiers([event modifierFlags]));
|
||||
}
|
||||
|
||||
- (void)draggingExited:(id <NSDraggingInfo>)sender {
|
||||
trayIcon_->NotifyDragExited();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@ namespace atom {
|
||||
|
||||
class TrayIconObserver {
|
||||
public:
|
||||
virtual void OnClicked(const gfx::Rect& bounds, int modifiers) {}
|
||||
virtual void OnClicked(const gfx::Rect& bounds,
|
||||
const gfx::Point& location,
|
||||
int modifiers) {}
|
||||
virtual void OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {}
|
||||
virtual void OnBalloonShow() {}
|
||||
virtual void OnBalloonClicked() {}
|
||||
@@ -31,6 +33,7 @@ class TrayIconObserver {
|
||||
virtual void OnDragEnded() {}
|
||||
virtual void OnMouseEntered(const gfx::Point& location, int modifiers) {}
|
||||
virtual void OnMouseExited(const gfx::Point& location, int modifiers) {}
|
||||
virtual void OnMouseMoved(const gfx::Point& location, int modifiers) {}
|
||||
|
||||
protected:
|
||||
virtual ~TrayIconObserver() {}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "atom/browser/ui/views/autofill_popup_view.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/i18n/rtl.h"
|
||||
#include "cc/paint/skia_paint_canvas.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "ui/events/keycodes/keyboard_codes.h"
|
||||
#include "ui/gfx/canvas.h"
|
||||
@@ -229,7 +230,8 @@ void AutofillPopupView::OnPaint(gfx::Canvas* canvas) {
|
||||
bitmap.allocN32Pixels(popup_->popup_bounds_in_view_.width(),
|
||||
popup_->popup_bounds_in_view_.height(),
|
||||
true);
|
||||
draw_canvas = new gfx::Canvas(new SkCanvas(bitmap), 1.0);
|
||||
cc::SkiaPaintCanvas paint_canvas(new SkCanvas(bitmap));
|
||||
draw_canvas = new gfx::Canvas(&paint_canvas, 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -358,7 +360,7 @@ bool AutofillPopupView::HandleKeyPressEvent(
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
if (!popup_)
|
||||
return false;
|
||||
switch (event.windowsKeyCode) {
|
||||
switch (event.windows_key_code) {
|
||||
case ui::VKEY_UP:
|
||||
SelectPreviousLine();
|
||||
return true;
|
||||
|
||||
@@ -153,8 +153,9 @@ void MenuBar::OnMenuButtonClicked(views::MenuButton* source,
|
||||
return;
|
||||
}
|
||||
|
||||
MenuDelegate menu_delegate(this);
|
||||
menu_delegate.RunMenu(menu_model_->GetSubmenuModelAt(id), source);
|
||||
// Deleted in MenuDelegate::OnMenuClosed
|
||||
MenuDelegate* menu_delegate = new MenuDelegate(this);
|
||||
menu_delegate->RunMenu(menu_model_->GetSubmenuModelAt(id), source);
|
||||
}
|
||||
|
||||
void MenuBar::OnNativeThemeChanged(const ui::NativeTheme* theme) {
|
||||
|
||||
@@ -95,24 +95,36 @@ void MenuDelegate::WillHideMenu(views::MenuItemView* menu) {
|
||||
adapter_->WillHideMenu(menu);
|
||||
}
|
||||
|
||||
void MenuDelegate::OnMenuClosed(views::MenuItemView* menu,
|
||||
views::MenuRunner::RunResult result) {
|
||||
// Only switch to new menu when current menu is closed.
|
||||
if (button_to_open_)
|
||||
button_to_open_->Activate(nullptr);
|
||||
delete this;
|
||||
}
|
||||
|
||||
views::MenuItemView* MenuDelegate::GetSiblingMenu(
|
||||
views::MenuItemView* menu,
|
||||
const gfx::Point& screen_point,
|
||||
views::MenuAnchorPosition* anchor,
|
||||
bool* has_mnemonics,
|
||||
views::MenuButton**) {
|
||||
// TODO(zcbenz): We should follow Chromium's logics on implementing the
|
||||
// sibling menu switches, this code is almost a hack.
|
||||
views::MenuButton* button;
|
||||
AtomMenuModel* model;
|
||||
if (menu_bar_->GetMenuButtonFromScreenPoint(screen_point, &model, &button) &&
|
||||
button->tag() != id_) {
|
||||
DCHECK(menu_runner_->IsRunning());
|
||||
menu_runner_->Cancel();
|
||||
// After canceling the menu, we need to wait until next tick
|
||||
// so we are out of nested message loop.
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(base::IgnoreResult(&views::MenuButton::Activate),
|
||||
base::Unretained(button), nullptr));
|
||||
bool switch_in_progress = !!button_to_open_;
|
||||
// Always update target to open.
|
||||
button_to_open_ = button;
|
||||
// Switching menu asyncnously to avoid crash.
|
||||
if (!switch_in_progress) {
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&views::MenuRunner::Cancel,
|
||||
base::Unretained(menu_runner_.get())));
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
@@ -40,6 +40,8 @@ class MenuDelegate : public views::MenuDelegate {
|
||||
void SelectionChanged(views::MenuItemView* menu) override;
|
||||
void WillShowMenu(views::MenuItemView* menu) override;
|
||||
void WillHideMenu(views::MenuItemView* menu) override;
|
||||
void OnMenuClosed(views::MenuItemView* menu,
|
||||
views::MenuRunner::RunResult result) override;
|
||||
views::MenuItemView* GetSiblingMenu(
|
||||
views::MenuItemView* menu,
|
||||
const gfx::Point& screen_point,
|
||||
@@ -53,6 +55,9 @@ class MenuDelegate : public views::MenuDelegate {
|
||||
std::unique_ptr<views::MenuDelegate> adapter_;
|
||||
std::unique_ptr<views::MenuRunner> menu_runner_;
|
||||
|
||||
// The menu button to switch to.
|
||||
views::MenuButton* button_to_open_ = nullptr;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MenuDelegate);
|
||||
};
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ void PdfViewerHandler::OnZoomLevelChanged(content::WebContents* web_contents,
|
||||
double level, bool is_temporary) {
|
||||
if (web_ui()->GetWebContents() == web_contents) {
|
||||
CallJavascriptFunction("cr.webUIListenerCallback",
|
||||
base::StringValue("onZoomLevelChanged"),
|
||||
base::Value("onZoomLevelChanged"),
|
||||
base::Value(content::ZoomLevelToZoomFactor(level)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ class PdfViewerUI::ResourceRequester
|
||||
request->set_method("GET");
|
||||
|
||||
content::ResourceDispatcherHostImpl::Get()->InitializeURLRequest(
|
||||
request.get(), content::Referrer(url, blink::WebReferrerPolicyDefault),
|
||||
request.get(), content::Referrer(url, blink::kWebReferrerPolicyDefault),
|
||||
false, // download.
|
||||
render_process_id, render_view_id, render_frame_id,
|
||||
content::PREVIEWS_OFF, resource_context);
|
||||
|
||||
@@ -55,7 +55,9 @@ void NotifyIcon::HandleClickEvent(int modifiers,
|
||||
if (double_button_click) // double left click
|
||||
NotifyDoubleClicked(bounds, modifiers);
|
||||
else // single left click
|
||||
NotifyClicked(bounds, modifiers);
|
||||
NotifyClicked(bounds,
|
||||
display::Screen::GetScreen()->GetCursorScreenPoint(),
|
||||
modifiers);
|
||||
return;
|
||||
} else if (!double_button_click) { // single right click
|
||||
if (menu_model_)
|
||||
@@ -147,10 +149,10 @@ void NotifyIcon::PopUpContextMenu(const gfx::Point& pos,
|
||||
if (pos.IsOrigin())
|
||||
rect.set_origin(display::Screen::GetScreen()->GetCursorScreenPoint());
|
||||
|
||||
views::MenuRunner menu_runner(
|
||||
menu_runner_.reset(new views::MenuRunner(
|
||||
menu_model != nullptr ? menu_model : menu_model_,
|
||||
views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
|
||||
ignore_result(menu_runner.RunMenuAt(
|
||||
views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS));
|
||||
ignore_result(menu_runner_->RunMenuAt(
|
||||
NULL, NULL, rect, views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@ namespace gfx {
|
||||
class Point;
|
||||
}
|
||||
|
||||
namespace views {
|
||||
class MenuRunner;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class NotifyIconHost;
|
||||
@@ -77,6 +81,9 @@ class NotifyIcon : public TrayIcon {
|
||||
// The context menu.
|
||||
AtomMenuModel* menu_model_;
|
||||
|
||||
// Context menu associated with this icon (if any).
|
||||
std::unique_ptr<views::MenuRunner> menu_runner_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NotifyIcon);
|
||||
};
|
||||
|
||||
|
||||
@@ -81,6 +81,9 @@ void WindowList::RemoveObserver(WindowListObserver* observer) {
|
||||
// static
|
||||
void WindowList::CloseAllWindows() {
|
||||
WindowVector windows = GetInstance()->windows_;
|
||||
#if defined(OS_MACOSX)
|
||||
std::reverse(windows.begin(), windows.end());
|
||||
#endif
|
||||
for (const auto& window : windows)
|
||||
if (!window->IsClosed())
|
||||
window->Close();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/base/clipboard/scoped_clipboard_writer.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
@@ -166,7 +167,13 @@ gfx::Image Clipboard::ReadImage(mate::Arguments* args) {
|
||||
|
||||
void Clipboard::WriteImage(const gfx::Image& image, mate::Arguments* args) {
|
||||
ui::ScopedClipboardWriter writer(GetClipboardType(args));
|
||||
writer.WriteImage(image.AsBitmap());
|
||||
SkBitmap bmp;
|
||||
// TODO(ferreus): Replace with sk_tools_utils::copy_to (chrome60)
|
||||
if (image.AsBitmap().deepCopyTo(&bmp)) {
|
||||
writer.WriteImage(bmp);
|
||||
} else {
|
||||
writer.WriteImage(image.AsBitmap());
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
|
||||
@@ -541,6 +541,13 @@ mate::Handle<NativeImage> NativeImage::CreateFromDataURL(
|
||||
return CreateEmpty(isolate);
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
mate::Handle<NativeImage> NativeImage::CreateFromNamedImage(
|
||||
mate::Arguments* args, const std::string& name) {
|
||||
return CreateEmpty(args->isolate());
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
void NativeImage::BuildPrototype(
|
||||
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
|
||||
@@ -609,6 +616,8 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
dict.SetMethod("createFromBuffer", &atom::api::NativeImage::CreateFromBuffer);
|
||||
dict.SetMethod("createFromDataURL",
|
||||
&atom::api::NativeImage::CreateFromDataURL);
|
||||
dict.SetMethod("createFromNamedImage",
|
||||
&atom::api::NativeImage::CreateFromNamedImage);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -53,6 +53,8 @@ class NativeImage : public mate::Wrappable<NativeImage> {
|
||||
mate::Arguments* args, v8::Local<v8::Value> buffer);
|
||||
static mate::Handle<NativeImage> CreateFromDataURL(
|
||||
v8::Isolate* isolate, const GURL& url);
|
||||
static mate::Handle<NativeImage> CreateFromNamedImage(
|
||||
mate::Arguments* args, const std::string& name);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
@@ -6,10 +6,56 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "ui/gfx/color_utils.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
#include "ui/gfx/image/image_skia_operations.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
NSData* bufferFromNSImage(NSImage* image) {
|
||||
CGImageRef ref = [image CGImageForProposedRect:nil context:nil hints:nil];
|
||||
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithCGImage:ref];
|
||||
[rep setSize:[image size]];
|
||||
return [rep representationUsingType:NSPNGFileType properties:[[NSDictionary alloc] init]];
|
||||
}
|
||||
|
||||
double safeShift(double in, double def) {
|
||||
if (in >= 0 || in <= 1 || in == def) return in;
|
||||
return def;
|
||||
}
|
||||
|
||||
mate::Handle<NativeImage> NativeImage::CreateFromNamedImage(
|
||||
mate::Arguments* args, const std::string& name) {
|
||||
@autoreleasepool {
|
||||
std::vector<double> hsl_shift;
|
||||
NSImage* image = [NSImage imageNamed:base::SysUTF8ToNSString(name)];
|
||||
if (!image.valid) {
|
||||
return CreateEmpty(args->isolate());
|
||||
}
|
||||
|
||||
NSData* png_data = bufferFromNSImage(image);
|
||||
|
||||
if (args->GetNext(&hsl_shift) && hsl_shift.size() == 3) {
|
||||
gfx::Image gfx_image = gfx::Image::CreateFrom1xPNGBytes(
|
||||
reinterpret_cast<const unsigned char*>((char *) [png_data bytes]), [png_data length]);
|
||||
color_utils::HSL shift = {
|
||||
safeShift(hsl_shift[0], -1),
|
||||
safeShift(hsl_shift[1], 0.5),
|
||||
safeShift(hsl_shift[2], 0.5)
|
||||
};
|
||||
png_data = bufferFromNSImage(gfx::Image(
|
||||
gfx::ImageSkiaOperations::CreateHSLShiftedImage(
|
||||
gfx_image.AsImageSkia(), shift)).CopyNSImage());
|
||||
}
|
||||
|
||||
return CreateFromPNG(args->isolate(), (char *) [png_data bytes], [png_data length]);
|
||||
}
|
||||
}
|
||||
|
||||
void NativeImage::SetTemplateImage(bool setAsTemplate) {
|
||||
[image_.AsNSImage() setTemplate:setAsTemplate];
|
||||
}
|
||||
|
||||
@@ -164,7 +164,15 @@ v8::Local<v8::Value> AtomBindings::GetSystemMemoryInfo(v8::Isolate* isolate,
|
||||
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("total", mem_info.total);
|
||||
dict.Set("free", mem_info.free);
|
||||
|
||||
// See Chromium's "base/process/process_metrics.h" for an explanation.
|
||||
int free =
|
||||
#if defined(OS_WIN)
|
||||
mem_info.avail_phys;
|
||||
#else
|
||||
mem_info.free;
|
||||
#endif
|
||||
dict.Set("free", free);
|
||||
|
||||
// NB: These return bogus values on macOS
|
||||
#if !defined(OS_MACOSX)
|
||||
@@ -180,7 +188,14 @@ v8::Local<v8::Value> AtomBindings::GetCPUUsage(v8::Isolate* isolate) {
|
||||
int processor_count = base::SysInfo::NumberOfProcessors();
|
||||
dict.Set("percentCPUUsage",
|
||||
metrics_->GetPlatformIndependentCPUUsage() / processor_count);
|
||||
|
||||
// NB: This will throw NOTIMPLEMENTED() on Windows
|
||||
// For backwards compatibility, we'll return 0
|
||||
#if !defined(OS_WIN)
|
||||
dict.Set("idleWakeupsPerSecond", metrics_->GetIdleWakeupsPerSecond());
|
||||
#else
|
||||
dict.Set("idleWakeupsPerSecond", 0);
|
||||
#endif
|
||||
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ v8::Local<v8::Value> CallMethodWithArgs(v8::Isolate* isolate,
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
// Use node::MakeCallback to call the callback, and it will also run pending
|
||||
// tasks in Node.js.
|
||||
return node::MakeCallback(isolate, obj, method, args->size(), &args->front());
|
||||
return node::MakeCallback(isolate, obj, method, args->size(), &args->front(),
|
||||
{0, 0}).ToLocalChecked();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
@@ -19,11 +19,11 @@ namespace atom {
|
||||
namespace {
|
||||
|
||||
content::RenderView* GetCurrentRenderView() {
|
||||
WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext();
|
||||
WebLocalFrame* frame = WebLocalFrame::FrameForCurrentContext();
|
||||
if (!frame)
|
||||
return nullptr;
|
||||
|
||||
WebView* view = frame->view();
|
||||
WebView* view = frame->View();
|
||||
if (!view)
|
||||
return nullptr; // can happen during closing.
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "base/values.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "atom/node/osfhandle.h"
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
namespace asar {
|
||||
@@ -118,7 +118,7 @@ Archive::Archive(const base::FilePath& path)
|
||||
: path_(path),
|
||||
file_(path_, base::File::FLAG_OPEN | base::File::FLAG_READ),
|
||||
#if defined(OS_WIN)
|
||||
fd_(node::open_osfhandle(
|
||||
fd_(_open_osfhandle(
|
||||
reinterpret_cast<intptr_t>(file_.GetPlatformFile()), 0)),
|
||||
#elif defined(OS_POSIX)
|
||||
fd_(file_.GetPlatformFile()),
|
||||
@@ -131,7 +131,7 @@ Archive::Archive(const base::FilePath& path)
|
||||
Archive::~Archive() {
|
||||
#if defined(OS_WIN)
|
||||
if (fd_ != -1) {
|
||||
node::close(fd_);
|
||||
_close(fd_);
|
||||
// Don't close the handle since we already closed the fd.
|
||||
file_.TakePlatformFile();
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#define ATOM_COMMON_ATOM_VERSION_H_
|
||||
|
||||
#define ATOM_MAJOR_VERSION 1
|
||||
#define ATOM_MINOR_VERSION 7
|
||||
#define ATOM_PATCH_VERSION 8
|
||||
#define ATOM_MINOR_VERSION 8
|
||||
#define ATOM_PATCH_VERSION 2
|
||||
|
||||
#define ATOM_VERSION_IS_RELEASE 1
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef ATOM_COMMON_CHROME_VERSION_H_
|
||||
#define ATOM_COMMON_CHROME_VERSION_H_
|
||||
|
||||
#define CHROME_VERSION_STRING "58.0.3029.110"
|
||||
#define CHROME_VERSION_STRING "59.0.3071.115"
|
||||
#define CHROME_VERSION "v" CHROME_VERSION_STRING
|
||||
|
||||
#endif // ATOM_COMMON_CHROME_VERSION_H_
|
||||
|
||||
@@ -179,27 +179,27 @@ ui::KeyboardCode KeyboardCodeFromStr(const std::string& str, bool* shifted) {
|
||||
int WebEventModifiersToEventFlags(int modifiers) {
|
||||
int flags = 0;
|
||||
|
||||
if (modifiers & blink::WebInputEvent::ShiftKey)
|
||||
if (modifiers & blink::WebInputEvent::kShiftKey)
|
||||
flags |= ui::EF_SHIFT_DOWN;
|
||||
if (modifiers & blink::WebInputEvent::ControlKey)
|
||||
if (modifiers & blink::WebInputEvent::kControlKey)
|
||||
flags |= ui::EF_CONTROL_DOWN;
|
||||
if (modifiers & blink::WebInputEvent::AltKey)
|
||||
if (modifiers & blink::WebInputEvent::kAltKey)
|
||||
flags |= ui::EF_ALT_DOWN;
|
||||
if (modifiers & blink::WebInputEvent::MetaKey)
|
||||
if (modifiers & blink::WebInputEvent::kMetaKey)
|
||||
flags |= ui::EF_COMMAND_DOWN;
|
||||
if (modifiers & blink::WebInputEvent::CapsLockOn)
|
||||
if (modifiers & blink::WebInputEvent::kCapsLockOn)
|
||||
flags |= ui::EF_CAPS_LOCK_ON;
|
||||
if (modifiers & blink::WebInputEvent::NumLockOn)
|
||||
if (modifiers & blink::WebInputEvent::kNumLockOn)
|
||||
flags |= ui::EF_NUM_LOCK_ON;
|
||||
if (modifiers & blink::WebInputEvent::ScrollLockOn)
|
||||
if (modifiers & blink::WebInputEvent::kScrollLockOn)
|
||||
flags |= ui::EF_SCROLL_LOCK_ON;
|
||||
if (modifiers & blink::WebInputEvent::LeftButtonDown)
|
||||
if (modifiers & blink::WebInputEvent::kLeftButtonDown)
|
||||
flags |= ui::EF_LEFT_MOUSE_BUTTON;
|
||||
if (modifiers & blink::WebInputEvent::MiddleButtonDown)
|
||||
if (modifiers & blink::WebInputEvent::kMiddleButtonDown)
|
||||
flags |= ui::EF_MIDDLE_MOUSE_BUTTON;
|
||||
if (modifiers & blink::WebInputEvent::RightButtonDown)
|
||||
if (modifiers & blink::WebInputEvent::kRightButtonDown)
|
||||
flags |= ui::EF_RIGHT_MOUSE_BUTTON;
|
||||
if (modifiers & blink::WebInputEvent::IsAutoRepeat)
|
||||
if (modifiers & blink::WebInputEvent::kIsAutoRepeat)
|
||||
flags |= ui::EF_IS_REPEAT;
|
||||
|
||||
return flags;
|
||||
|
||||
@@ -9,52 +9,52 @@ using Cursor = blink::WebCursorInfo::Type;
|
||||
|
||||
namespace atom {
|
||||
|
||||
std::string CursorTypeToString(const content::WebCursor::CursorInfo& info) {
|
||||
std::string CursorTypeToString(const content::CursorInfo& info) {
|
||||
switch (info.type) {
|
||||
case Cursor::TypePointer: return "default";
|
||||
case Cursor::TypeCross: return "crosshair";
|
||||
case Cursor::TypeHand: return "pointer";
|
||||
case Cursor::TypeIBeam: return "text";
|
||||
case Cursor::TypeWait: return "wait";
|
||||
case Cursor::TypeHelp: return "help";
|
||||
case Cursor::TypeEastResize: return "e-resize";
|
||||
case Cursor::TypeNorthResize: return "n-resize";
|
||||
case Cursor::TypeNorthEastResize: return "ne-resize";
|
||||
case Cursor::TypeNorthWestResize: return "nw-resize";
|
||||
case Cursor::TypeSouthResize: return "s-resize";
|
||||
case Cursor::TypeSouthEastResize: return "se-resize";
|
||||
case Cursor::TypeSouthWestResize: return "sw-resize";
|
||||
case Cursor::TypeWestResize: return "w-resize";
|
||||
case Cursor::TypeNorthSouthResize: return "ns-resize";
|
||||
case Cursor::TypeEastWestResize: return "ew-resize";
|
||||
case Cursor::TypeNorthEastSouthWestResize: return "nesw-resize";
|
||||
case Cursor::TypeNorthWestSouthEastResize: return "nwse-resize";
|
||||
case Cursor::TypeColumnResize: return "col-resize";
|
||||
case Cursor::TypeRowResize: return "row-resize";
|
||||
case Cursor::TypeMiddlePanning: return "m-panning";
|
||||
case Cursor::TypeEastPanning: return "e-panning";
|
||||
case Cursor::TypeNorthPanning: return "n-panning";
|
||||
case Cursor::TypeNorthEastPanning: return "ne-panning";
|
||||
case Cursor::TypeNorthWestPanning: return "nw-panning";
|
||||
case Cursor::TypeSouthPanning: return "s-panning";
|
||||
case Cursor::TypeSouthEastPanning: return "se-panning";
|
||||
case Cursor::TypeSouthWestPanning: return "sw-panning";
|
||||
case Cursor::TypeWestPanning: return "w-panning";
|
||||
case Cursor::TypeMove: return "move";
|
||||
case Cursor::TypeVerticalText: return "vertical-text";
|
||||
case Cursor::TypeCell: return "cell";
|
||||
case Cursor::TypeContextMenu: return "context-menu";
|
||||
case Cursor::TypeAlias: return "alias";
|
||||
case Cursor::TypeProgress: return "progress";
|
||||
case Cursor::TypeNoDrop: return "nodrop";
|
||||
case Cursor::TypeCopy: return "copy";
|
||||
case Cursor::TypeNone: return "none";
|
||||
case Cursor::TypeNotAllowed: return "not-allowed";
|
||||
case Cursor::TypeZoomIn: return "zoom-in";
|
||||
case Cursor::TypeZoomOut: return "zoom-out";
|
||||
case Cursor::TypeGrab: return "grab";
|
||||
case Cursor::TypeGrabbing: return "grabbing";
|
||||
case Cursor::TypeCustom: return "custom";
|
||||
case Cursor::kTypePointer: return "default";
|
||||
case Cursor::kTypeCross: return "crosshair";
|
||||
case Cursor::kTypeHand: return "pointer";
|
||||
case Cursor::kTypeIBeam: return "text";
|
||||
case Cursor::kTypeWait: return "wait";
|
||||
case Cursor::kTypeHelp: return "help";
|
||||
case Cursor::kTypeEastResize: return "e-resize";
|
||||
case Cursor::kTypeNorthResize: return "n-resize";
|
||||
case Cursor::kTypeNorthEastResize: return "ne-resize";
|
||||
case Cursor::kTypeNorthWestResize: return "nw-resize";
|
||||
case Cursor::kTypeSouthResize: return "s-resize";
|
||||
case Cursor::kTypeSouthEastResize: return "se-resize";
|
||||
case Cursor::kTypeSouthWestResize: return "sw-resize";
|
||||
case Cursor::kTypeWestResize: return "w-resize";
|
||||
case Cursor::kTypeNorthSouthResize: return "ns-resize";
|
||||
case Cursor::kTypeEastWestResize: return "ew-resize";
|
||||
case Cursor::kTypeNorthEastSouthWestResize: return "nesw-resize";
|
||||
case Cursor::kTypeNorthWestSouthEastResize: return "nwse-resize";
|
||||
case Cursor::kTypeColumnResize: return "col-resize";
|
||||
case Cursor::kTypeRowResize: return "row-resize";
|
||||
case Cursor::kTypeMiddlePanning: return "m-panning";
|
||||
case Cursor::kTypeEastPanning: return "e-panning";
|
||||
case Cursor::kTypeNorthPanning: return "n-panning";
|
||||
case Cursor::kTypeNorthEastPanning: return "ne-panning";
|
||||
case Cursor::kTypeNorthWestPanning: return "nw-panning";
|
||||
case Cursor::kTypeSouthPanning: return "s-panning";
|
||||
case Cursor::kTypeSouthEastPanning: return "se-panning";
|
||||
case Cursor::kTypeSouthWestPanning: return "sw-panning";
|
||||
case Cursor::kTypeWestPanning: return "w-panning";
|
||||
case Cursor::kTypeMove: return "move";
|
||||
case Cursor::kTypeVerticalText: return "vertical-text";
|
||||
case Cursor::kTypeCell: return "cell";
|
||||
case Cursor::kTypeContextMenu: return "context-menu";
|
||||
case Cursor::kTypeAlias: return "alias";
|
||||
case Cursor::kTypeProgress: return "progress";
|
||||
case Cursor::kTypeNoDrop: return "nodrop";
|
||||
case Cursor::kTypeCopy: return "copy";
|
||||
case Cursor::kTypeNone: return "none";
|
||||
case Cursor::kTypeNotAllowed: return "not-allowed";
|
||||
case Cursor::kTypeZoomIn: return "zoom-in";
|
||||
case Cursor::kTypeZoomOut: return "zoom-out";
|
||||
case Cursor::kTypeGrab: return "grab";
|
||||
case Cursor::kTypeGrabbing: return "grabbing";
|
||||
case Cursor::kTypeCustom: return "custom";
|
||||
default: return "default";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
namespace atom {
|
||||
|
||||
// Returns the cursor's type as a string.
|
||||
std::string CursorTypeToString(const content::WebCursor::CursorInfo& info);
|
||||
std::string CursorTypeToString(const content::CursorInfo& info);
|
||||
|
||||
} // namespace atom
|
||||
|
||||
|
||||
@@ -54,33 +54,33 @@ struct Converter<blink::WebInputEvent::Type> {
|
||||
blink::WebInputEvent::Type* out) {
|
||||
std::string type = base::ToLowerASCII(V8ToString(val));
|
||||
if (type == "mousedown")
|
||||
*out = blink::WebInputEvent::MouseDown;
|
||||
*out = blink::WebInputEvent::kMouseDown;
|
||||
else if (type == "mouseup")
|
||||
*out = blink::WebInputEvent::MouseUp;
|
||||
*out = blink::WebInputEvent::kMouseUp;
|
||||
else if (type == "mousemove")
|
||||
*out = blink::WebInputEvent::MouseMove;
|
||||
*out = blink::WebInputEvent::kMouseMove;
|
||||
else if (type == "mouseenter")
|
||||
*out = blink::WebInputEvent::MouseEnter;
|
||||
*out = blink::WebInputEvent::kMouseEnter;
|
||||
else if (type == "mouseleave")
|
||||
*out = blink::WebInputEvent::MouseLeave;
|
||||
*out = blink::WebInputEvent::kMouseLeave;
|
||||
else if (type == "contextmenu")
|
||||
*out = blink::WebInputEvent::ContextMenu;
|
||||
*out = blink::WebInputEvent::kContextMenu;
|
||||
else if (type == "mousewheel")
|
||||
*out = blink::WebInputEvent::MouseWheel;
|
||||
*out = blink::WebInputEvent::kMouseWheel;
|
||||
else if (type == "keydown")
|
||||
*out = blink::WebInputEvent::RawKeyDown;
|
||||
*out = blink::WebInputEvent::kRawKeyDown;
|
||||
else if (type == "keyup")
|
||||
*out = blink::WebInputEvent::KeyUp;
|
||||
*out = blink::WebInputEvent::kKeyUp;
|
||||
else if (type == "char")
|
||||
*out = blink::WebInputEvent::Char;
|
||||
*out = blink::WebInputEvent::kChar;
|
||||
else if (type == "touchstart")
|
||||
*out = blink::WebInputEvent::TouchStart;
|
||||
*out = blink::WebInputEvent::kTouchStart;
|
||||
else if (type == "touchmove")
|
||||
*out = blink::WebInputEvent::TouchMove;
|
||||
*out = blink::WebInputEvent::kTouchMove;
|
||||
else if (type == "touchend")
|
||||
*out = blink::WebInputEvent::TouchEnd;
|
||||
*out = blink::WebInputEvent::kTouchEnd;
|
||||
else if (type == "touchcancel")
|
||||
*out = blink::WebInputEvent::TouchCancel;
|
||||
*out = blink::WebInputEvent::kTouchCancel;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -91,11 +91,11 @@ struct Converter<blink::WebMouseEvent::Button> {
|
||||
blink::WebMouseEvent::Button* out) {
|
||||
std::string button = base::ToLowerASCII(V8ToString(val));
|
||||
if (button == "left")
|
||||
*out = blink::WebMouseEvent::Button::Left;
|
||||
*out = blink::WebMouseEvent::Button::kLeft;
|
||||
else if (button == "middle")
|
||||
*out = blink::WebMouseEvent::Button::Middle;
|
||||
*out = blink::WebMouseEvent::Button::kMiddle;
|
||||
else if (button == "right")
|
||||
*out = blink::WebMouseEvent::Button::Right;
|
||||
*out = blink::WebMouseEvent::Button::kRight;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
@@ -108,37 +108,37 @@ struct Converter<blink::WebInputEvent::Modifiers> {
|
||||
blink::WebInputEvent::Modifiers* out) {
|
||||
std::string modifier = base::ToLowerASCII(V8ToString(val));
|
||||
if (modifier == "shift")
|
||||
*out = blink::WebInputEvent::ShiftKey;
|
||||
*out = blink::WebInputEvent::kShiftKey;
|
||||
else if (modifier == "control" || modifier == "ctrl")
|
||||
*out = blink::WebInputEvent::ControlKey;
|
||||
*out = blink::WebInputEvent::kControlKey;
|
||||
else if (modifier == "alt")
|
||||
*out = blink::WebInputEvent::AltKey;
|
||||
*out = blink::WebInputEvent::kAltKey;
|
||||
else if (modifier == "meta" || modifier == "command" || modifier == "cmd")
|
||||
*out = blink::WebInputEvent::MetaKey;
|
||||
*out = blink::WebInputEvent::kMetaKey;
|
||||
else if (modifier == "iskeypad")
|
||||
*out = blink::WebInputEvent::IsKeyPad;
|
||||
*out = blink::WebInputEvent::kIsKeyPad;
|
||||
else if (modifier == "isautorepeat")
|
||||
*out = blink::WebInputEvent::IsAutoRepeat;
|
||||
*out = blink::WebInputEvent::kIsAutoRepeat;
|
||||
else if (modifier == "leftbuttondown")
|
||||
*out = blink::WebInputEvent::LeftButtonDown;
|
||||
*out = blink::WebInputEvent::kLeftButtonDown;
|
||||
else if (modifier == "middlebuttondown")
|
||||
*out = blink::WebInputEvent::MiddleButtonDown;
|
||||
*out = blink::WebInputEvent::kMiddleButtonDown;
|
||||
else if (modifier == "rightbuttondown")
|
||||
*out = blink::WebInputEvent::RightButtonDown;
|
||||
*out = blink::WebInputEvent::kRightButtonDown;
|
||||
else if (modifier == "capslock")
|
||||
*out = blink::WebInputEvent::CapsLockOn;
|
||||
*out = blink::WebInputEvent::kCapsLockOn;
|
||||
else if (modifier == "numlock")
|
||||
*out = blink::WebInputEvent::NumLockOn;
|
||||
*out = blink::WebInputEvent::kNumLockOn;
|
||||
else if (modifier == "left")
|
||||
*out = blink::WebInputEvent::IsLeft;
|
||||
*out = blink::WebInputEvent::kIsLeft;
|
||||
else if (modifier == "right")
|
||||
*out = blink::WebInputEvent::IsRight;
|
||||
*out = blink::WebInputEvent::kIsRight;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
int GetWebInputEventType(v8::Isolate* isolate, v8::Local<v8::Value> val) {
|
||||
blink::WebInputEvent::Type type = blink::WebInputEvent::Undefined;
|
||||
blink::WebInputEvent::Type type = blink::WebInputEvent::kUndefined;
|
||||
mate::Dictionary dict;
|
||||
ConvertFromV8(isolate, val, &dict) && dict.Get("type", &type);
|
||||
return type;
|
||||
@@ -153,11 +153,11 @@ bool Converter<blink::WebInputEvent>::FromV8(
|
||||
blink::WebInputEvent::Type type;
|
||||
if (!dict.Get("type", &type))
|
||||
return false;
|
||||
out->setType(type);
|
||||
out->SetType(type);
|
||||
std::vector<blink::WebInputEvent::Modifiers> modifiers;
|
||||
if (dict.Get("modifiers", &modifiers))
|
||||
out->setModifiers(VectorToBitArray(modifiers));
|
||||
out->setTimeStampSeconds(base::Time::Now().ToDoubleT());
|
||||
out->SetModifiers(VectorToBitArray(modifiers));
|
||||
out->SetTimeStampSeconds(base::Time::Now().ToDoubleT());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -176,31 +176,31 @@ bool Converter<blink::WebKeyboardEvent>::FromV8(
|
||||
|
||||
bool shifted = false;
|
||||
ui::KeyboardCode keyCode = atom::KeyboardCodeFromStr(str, &shifted);
|
||||
out->windowsKeyCode = keyCode;
|
||||
out->windows_key_code = keyCode;
|
||||
if (shifted)
|
||||
out->setModifiers(out->modifiers() | blink::WebInputEvent::ShiftKey);
|
||||
out->SetModifiers(out->GetModifiers() | blink::WebInputEvent::kShiftKey);
|
||||
|
||||
ui::DomCode domCode = ui::UsLayoutKeyboardCodeToDomCode(keyCode);
|
||||
out->domCode = static_cast<int>(domCode);
|
||||
out->dom_code = static_cast<int>(domCode);
|
||||
|
||||
ui::DomKey domKey;
|
||||
ui::KeyboardCode dummy_code;
|
||||
int flags = atom::WebEventModifiersToEventFlags(out->modifiers());
|
||||
int flags = atom::WebEventModifiersToEventFlags(out->GetModifiers());
|
||||
if (ui::DomCodeToUsLayoutDomKey(domCode, flags, &domKey, &dummy_code))
|
||||
out->domKey = static_cast<int>(domKey);
|
||||
out->dom_key = static_cast<int>(domKey);
|
||||
|
||||
if ((out->type() == blink::WebInputEvent::Char ||
|
||||
out->type() == blink::WebInputEvent::RawKeyDown)) {
|
||||
if ((out->GetType() == blink::WebInputEvent::kChar ||
|
||||
out->GetType() == blink::WebInputEvent::kRawKeyDown)) {
|
||||
// Make sure to not read beyond the buffer in case some bad code doesn't
|
||||
// NULL-terminate it (this is called from plugins).
|
||||
size_t text_length_cap = blink::WebKeyboardEvent::textLengthCap;
|
||||
size_t text_length_cap = blink::WebKeyboardEvent::kTextLengthCap;
|
||||
base::string16 text16 = base::UTF8ToUTF16(str);
|
||||
|
||||
memset(out->text, 0, text_length_cap);
|
||||
memset(out->unmodifiedText, 0, text_length_cap);
|
||||
memset(out->unmodified_text, 0, text_length_cap);
|
||||
for (size_t i = 0; i < std::min(text_length_cap, text16.size()); ++i) {
|
||||
out->text[i] = text16[i];
|
||||
out->unmodifiedText[i] = text16[i];
|
||||
out->unmodified_text[i] = text16[i];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -222,20 +222,20 @@ v8::Local<v8::Value> Converter<content::NativeWebKeyboardEvent>::ToV8(
|
||||
v8::Isolate* isolate, const content::NativeWebKeyboardEvent& in) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
|
||||
if (in.type() == blink::WebInputEvent::Type::RawKeyDown)
|
||||
if (in.GetType() == blink::WebInputEvent::Type::kRawKeyDown)
|
||||
dict.Set("type", "keyDown");
|
||||
else if (in.type() == blink::WebInputEvent::Type::KeyUp)
|
||||
else if (in.GetType() == blink::WebInputEvent::Type::kKeyUp)
|
||||
dict.Set("type", "keyUp");
|
||||
dict.Set("key", ui::KeycodeConverter::DomKeyToKeyString(in.domKey));
|
||||
dict.Set("key", ui::KeycodeConverter::DomKeyToKeyString(in.dom_key));
|
||||
dict.Set("code", ui::KeycodeConverter::DomCodeToCodeString(
|
||||
static_cast<ui::DomCode>(in.domCode)));
|
||||
static_cast<ui::DomCode>(in.dom_code)));
|
||||
|
||||
using Modifiers = blink::WebInputEvent::Modifiers;
|
||||
dict.Set("isAutoRepeat", (in.modifiers() & Modifiers::IsAutoRepeat) != 0);
|
||||
dict.Set("shift", (in.modifiers() & Modifiers::ShiftKey) != 0);
|
||||
dict.Set("control", (in.modifiers() & Modifiers::ControlKey) != 0);
|
||||
dict.Set("alt", (in.modifiers() & Modifiers::AltKey) != 0);
|
||||
dict.Set("meta", (in.modifiers() & Modifiers::MetaKey) != 0);
|
||||
dict.Set("isAutoRepeat", (in.GetModifiers() & Modifiers::kIsAutoRepeat) != 0);
|
||||
dict.Set("shift", (in.GetModifiers() & Modifiers::kShiftKey) != 0);
|
||||
dict.Set("control", (in.GetModifiers() & Modifiers::kControlKey) != 0);
|
||||
dict.Set("alt", (in.GetModifiers() & Modifiers::kAltKey) != 0);
|
||||
dict.Set("meta", (in.GetModifiers() & Modifiers::kMetaKey) != 0);
|
||||
|
||||
return dict.GetHandle();
|
||||
}
|
||||
@@ -247,15 +247,25 @@ bool Converter<blink::WebMouseEvent>::FromV8(
|
||||
return false;
|
||||
if (!ConvertFromV8(isolate, val, static_cast<blink::WebInputEvent*>(out)))
|
||||
return false;
|
||||
if (!dict.Get("x", &out->x) || !dict.Get("y", &out->y))
|
||||
|
||||
float x = 0.f;
|
||||
float y = 0.f;
|
||||
if (!dict.Get("x", &x) || !dict.Get("y", &y))
|
||||
return false;
|
||||
out->SetPositionInWidget(x, y);
|
||||
|
||||
if (!dict.Get("button", &out->button))
|
||||
out->button = blink::WebMouseEvent::Button::Left;
|
||||
dict.Get("globalX", &out->globalX);
|
||||
dict.Get("globalY", &out->globalY);
|
||||
dict.Get("movementX", &out->movementX);
|
||||
dict.Get("movementY", &out->movementY);
|
||||
dict.Get("clickCount", &out->clickCount);
|
||||
out->button = blink::WebMouseEvent::Button::kLeft;
|
||||
|
||||
float global_x = 0.f;
|
||||
float global_y = 0.f;
|
||||
dict.Get("globalX", &global_x);
|
||||
dict.Get("globalY", &global_y);
|
||||
out->SetPositionInScreen(global_x, global_y);
|
||||
|
||||
dict.Get("movementX", &out->movement_x);
|
||||
dict.Get("movementY", &out->movement_y);
|
||||
dict.Get("clickCount", &out->click_count);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -267,20 +277,20 @@ bool Converter<blink::WebMouseWheelEvent>::FromV8(
|
||||
return false;
|
||||
if (!ConvertFromV8(isolate, val, static_cast<blink::WebMouseEvent*>(out)))
|
||||
return false;
|
||||
dict.Get("deltaX", &out->deltaX);
|
||||
dict.Get("deltaY", &out->deltaY);
|
||||
dict.Get("wheelTicksX", &out->wheelTicksX);
|
||||
dict.Get("wheelTicksY", &out->wheelTicksY);
|
||||
dict.Get("accelerationRatioX", &out->accelerationRatioX);
|
||||
dict.Get("accelerationRatioY", &out->accelerationRatioY);
|
||||
dict.Get("hasPreciseScrollingDeltas", &out->hasPreciseScrollingDeltas);
|
||||
dict.Get("deltaX", &out->delta_x);
|
||||
dict.Get("deltaY", &out->delta_y);
|
||||
dict.Get("wheelTicksX", &out->wheel_ticks_x);
|
||||
dict.Get("wheelTicksY", &out->wheel_ticks_y);
|
||||
dict.Get("accelerationRatioX", &out->acceleration_ratio_x);
|
||||
dict.Get("accelerationRatioY", &out->acceleration_ratio_y);
|
||||
dict.Get("hasPreciseScrollingDeltas", &out->has_precise_scrolling_deltas);
|
||||
|
||||
#if defined(USE_AURA)
|
||||
// Matches the behavior of ui/events/blink/web_input_event_traits.cc:
|
||||
bool can_scroll = true;
|
||||
if (dict.Get("canScroll", &can_scroll) && !can_scroll) {
|
||||
out->hasPreciseScrollingDeltas = false;
|
||||
out->setModifiers(out->modifiers() & ~blink::WebInputEvent::ControlKey);
|
||||
out->has_precise_scrolling_deltas = false;
|
||||
out->SetModifiers(out->GetModifiers() & ~blink::WebInputEvent::kControlKey);
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
@@ -321,18 +331,18 @@ bool Converter<blink::WebDeviceEmulationParams>::FromV8(
|
||||
if (dict.Get("screenPosition", &screen_position)) {
|
||||
screen_position = base::ToLowerASCII(screen_position);
|
||||
if (screen_position == "mobile")
|
||||
out->screenPosition = blink::WebDeviceEmulationParams::Mobile;
|
||||
out->screen_position = blink::WebDeviceEmulationParams::kMobile;
|
||||
else if (screen_position == "desktop")
|
||||
out->screenPosition = blink::WebDeviceEmulationParams::Desktop;
|
||||
out->screen_position = blink::WebDeviceEmulationParams::kDesktop;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
dict.Get("screenSize", &out->screenSize);
|
||||
dict.Get("viewPosition", &out->viewPosition);
|
||||
dict.Get("deviceScaleFactor", &out->deviceScaleFactor);
|
||||
dict.Get("viewSize", &out->viewSize);
|
||||
dict.Get("fitToView", &out->fitToView);
|
||||
dict.Get("screenSize", &out->screen_size);
|
||||
dict.Get("viewPosition", &out->view_position);
|
||||
dict.Get("deviceScaleFactor", &out->device_scale_factor);
|
||||
dict.Get("viewSize", &out->view_size);
|
||||
dict.Get("fitToView", &out->fit_to_view);
|
||||
dict.Get("offset", &out->offset);
|
||||
dict.Get("scale", &out->scale);
|
||||
return true;
|
||||
@@ -347,10 +357,10 @@ bool Converter<blink::WebFindOptions>::FromV8(
|
||||
return false;
|
||||
|
||||
dict.Get("forward", &out->forward);
|
||||
dict.Get("matchCase", &out->matchCase);
|
||||
dict.Get("findNext", &out->findNext);
|
||||
dict.Get("wordStart", &out->wordStart);
|
||||
dict.Get("medialCapitalAsWordStart", &out->medialCapitalAsWordStart);
|
||||
dict.Get("matchCase", &out->match_case);
|
||||
dict.Get("findNext", &out->find_next);
|
||||
dict.Get("wordStart", &out->word_start);
|
||||
dict.Get("medialCapitalAsWordStart", &out->medial_capital_as_word_start);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -358,17 +368,17 @@ bool Converter<blink::WebFindOptions>::FromV8(
|
||||
v8::Local<v8::Value> Converter<blink::WebContextMenuData::MediaType>::ToV8(
|
||||
v8::Isolate* isolate, const blink::WebContextMenuData::MediaType& in) {
|
||||
switch (in) {
|
||||
case blink::WebContextMenuData::MediaTypeImage:
|
||||
case blink::WebContextMenuData::kMediaTypeImage:
|
||||
return mate::StringToV8(isolate, "image");
|
||||
case blink::WebContextMenuData::MediaTypeVideo:
|
||||
case blink::WebContextMenuData::kMediaTypeVideo:
|
||||
return mate::StringToV8(isolate, "video");
|
||||
case blink::WebContextMenuData::MediaTypeAudio:
|
||||
case blink::WebContextMenuData::kMediaTypeAudio:
|
||||
return mate::StringToV8(isolate, "audio");
|
||||
case blink::WebContextMenuData::MediaTypeCanvas:
|
||||
case blink::WebContextMenuData::kMediaTypeCanvas:
|
||||
return mate::StringToV8(isolate, "canvas");
|
||||
case blink::WebContextMenuData::MediaTypeFile:
|
||||
case blink::WebContextMenuData::kMediaTypeFile:
|
||||
return mate::StringToV8(isolate, "file");
|
||||
case blink::WebContextMenuData::MediaTypePlugin:
|
||||
case blink::WebContextMenuData::kMediaTypePlugin:
|
||||
return mate::StringToV8(isolate, "plugin");
|
||||
default:
|
||||
return mate::StringToV8(isolate, "none");
|
||||
@@ -380,11 +390,11 @@ v8::Local<v8::Value> Converter<blink::WebContextMenuData::InputFieldType>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const blink::WebContextMenuData::InputFieldType& in) {
|
||||
switch (in) {
|
||||
case blink::WebContextMenuData::InputFieldTypePlainText:
|
||||
case blink::WebContextMenuData::kInputFieldTypePlainText:
|
||||
return mate::StringToV8(isolate, "plainText");
|
||||
case blink::WebContextMenuData::InputFieldTypePassword:
|
||||
case blink::WebContextMenuData::kInputFieldTypePassword:
|
||||
return mate::StringToV8(isolate, "password");
|
||||
case blink::WebContextMenuData::InputFieldTypeOther:
|
||||
case blink::WebContextMenuData::kInputFieldTypeOther:
|
||||
return mate::StringToV8(isolate, "other");
|
||||
default:
|
||||
return mate::StringToV8(isolate, "none");
|
||||
@@ -394,16 +404,16 @@ v8::Local<v8::Value> Converter<blink::WebContextMenuData::InputFieldType>::ToV8(
|
||||
v8::Local<v8::Value> EditFlagsToV8(v8::Isolate* isolate, int editFlags) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("canUndo",
|
||||
!!(editFlags & blink::WebContextMenuData::CanUndo));
|
||||
!!(editFlags & blink::WebContextMenuData::kCanUndo));
|
||||
dict.Set("canRedo",
|
||||
!!(editFlags & blink::WebContextMenuData::CanRedo));
|
||||
!!(editFlags & blink::WebContextMenuData::kCanRedo));
|
||||
dict.Set("canCut",
|
||||
!!(editFlags & blink::WebContextMenuData::CanCut));
|
||||
!!(editFlags & blink::WebContextMenuData::kCanCut));
|
||||
dict.Set("canCopy",
|
||||
!!(editFlags & blink::WebContextMenuData::CanCopy));
|
||||
!!(editFlags & blink::WebContextMenuData::kCanCopy));
|
||||
|
||||
bool pasteFlag = false;
|
||||
if (editFlags & blink::WebContextMenuData::CanPaste) {
|
||||
if (editFlags & blink::WebContextMenuData::kCanPaste) {
|
||||
std::vector<base::string16> types;
|
||||
bool ignore;
|
||||
ui::Clipboard::GetForCurrentThread()->ReadAvailableTypes(
|
||||
@@ -413,9 +423,9 @@ v8::Local<v8::Value> EditFlagsToV8(v8::Isolate* isolate, int editFlags) {
|
||||
dict.Set("canPaste", pasteFlag);
|
||||
|
||||
dict.Set("canDelete",
|
||||
!!(editFlags & blink::WebContextMenuData::CanDelete));
|
||||
!!(editFlags & blink::WebContextMenuData::kCanDelete));
|
||||
dict.Set("canSelectAll",
|
||||
!!(editFlags & blink::WebContextMenuData::CanSelectAll));
|
||||
!!(editFlags & blink::WebContextMenuData::kCanSelectAll));
|
||||
|
||||
return mate::ConvertToV8(isolate, dict);
|
||||
}
|
||||
@@ -423,21 +433,21 @@ v8::Local<v8::Value> EditFlagsToV8(v8::Isolate* isolate, int editFlags) {
|
||||
v8::Local<v8::Value> MediaFlagsToV8(v8::Isolate* isolate, int mediaFlags) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("inError",
|
||||
!!(mediaFlags & blink::WebContextMenuData::MediaInError));
|
||||
!!(mediaFlags & blink::WebContextMenuData::kMediaInError));
|
||||
dict.Set("isPaused",
|
||||
!!(mediaFlags & blink::WebContextMenuData::MediaPaused));
|
||||
!!(mediaFlags & blink::WebContextMenuData::kMediaPaused));
|
||||
dict.Set("isMuted",
|
||||
!!(mediaFlags & blink::WebContextMenuData::MediaMuted));
|
||||
!!(mediaFlags & blink::WebContextMenuData::kMediaMuted));
|
||||
dict.Set("hasAudio",
|
||||
!!(mediaFlags & blink::WebContextMenuData::MediaHasAudio));
|
||||
!!(mediaFlags & blink::WebContextMenuData::kMediaHasAudio));
|
||||
dict.Set("isLooping",
|
||||
(mediaFlags & blink::WebContextMenuData::MediaLoop) != 0);
|
||||
(mediaFlags & blink::WebContextMenuData::kMediaLoop) != 0);
|
||||
dict.Set("isControlsVisible",
|
||||
(mediaFlags & blink::WebContextMenuData::MediaControls) != 0);
|
||||
(mediaFlags & blink::WebContextMenuData::kMediaControls) != 0);
|
||||
dict.Set("canToggleControls",
|
||||
!!(mediaFlags & blink::WebContextMenuData::MediaCanToggleControls));
|
||||
!!(mediaFlags & blink::WebContextMenuData::kMediaCanToggleControls));
|
||||
dict.Set("canRotate",
|
||||
!!(mediaFlags & blink::WebContextMenuData::MediaCanRotate));
|
||||
!!(mediaFlags & blink::WebContextMenuData::kMediaCanRotate));
|
||||
return mate::ConvertToV8(isolate, dict);
|
||||
}
|
||||
|
||||
@@ -447,7 +457,7 @@ v8::Local<v8::Value> Converter<blink::WebCache::ResourceTypeStat>::ToV8(
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("count", static_cast<uint32_t>(stat.count));
|
||||
dict.Set("size", static_cast<double>(stat.size));
|
||||
dict.Set("liveSize", static_cast<double>(stat.decodedSize));
|
||||
dict.Set("liveSize", static_cast<double>(stat.decoded_size));
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
@@ -457,8 +467,8 @@ v8::Local<v8::Value> Converter<blink::WebCache::ResourceTypeStats>::ToV8(
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("images", stats.images);
|
||||
dict.Set("scripts", stats.scripts);
|
||||
dict.Set("cssStyleSheets", stats.cssStyleSheets);
|
||||
dict.Set("xslStyleSheets", stats.xslStyleSheets);
|
||||
dict.Set("cssStyleSheets", stats.css_style_sheets);
|
||||
dict.Set("xslStyleSheets", stats.xsl_style_sheets);
|
||||
dict.Set("fonts", stats.fonts);
|
||||
dict.Set("other", stats.other);
|
||||
return dict.GetHandle();
|
||||
|
||||
@@ -109,7 +109,7 @@ v8::Local<v8::Value> Converter<ContextMenuParamsWithWebContents>::ToV8(
|
||||
dict.Set("mediaType", params.media_type);
|
||||
dict.Set("mediaFlags", MediaFlagsToV8(isolate, params.media_flags));
|
||||
bool has_image_contents =
|
||||
(params.media_type == blink::WebContextMenuData::MediaTypeImage) &&
|
||||
(params.media_type == blink::WebContextMenuData::kMediaTypeImage) &&
|
||||
params.has_image_contents;
|
||||
dict.Set("hasImageContents", has_image_contents);
|
||||
dict.Set("isEditable", params.is_editable);
|
||||
@@ -215,7 +215,7 @@ Converter<scoped_refptr<ResourceRequestBodyImpl>>::ToV8(
|
||||
auto type = element.type();
|
||||
if (type == ResourceRequestBodyImpl::Element::TYPE_BYTES) {
|
||||
std::unique_ptr<base::Value> bytes(
|
||||
base::BinaryValue::CreateWithCopiedBuffer(
|
||||
base::Value::CreateWithCopiedBuffer(
|
||||
element.bytes(), static_cast<size_t>(element.length())));
|
||||
post_data_dict->SetString("type", "rawData");
|
||||
post_data_dict->Set("bytes", std::move(bytes));
|
||||
@@ -260,7 +260,7 @@ bool Converter<scoped_refptr<ResourceRequestBodyImpl>>::FromV8(
|
||||
return false;
|
||||
dict->GetString("type", &type);
|
||||
if (type == "rawData") {
|
||||
base::BinaryValue* bytes = nullptr;
|
||||
base::Value* bytes = nullptr;
|
||||
dict->GetBinary("bytes", &bytes);
|
||||
(*out)->AppendBytes(bytes->GetBuffer(), bytes->GetSize());
|
||||
} else if (type == "file") {
|
||||
|
||||
@@ -196,7 +196,7 @@ void GetUploadData(base::ListValue* upload_data_list,
|
||||
const net::UploadBytesElementReader* bytes_reader =
|
||||
reader->AsBytesReader();
|
||||
std::unique_ptr<base::Value> bytes(
|
||||
base::BinaryValue::CreateWithCopiedBuffer(bytes_reader->bytes(),
|
||||
base::Value::CreateWithCopiedBuffer(bytes_reader->bytes(),
|
||||
bytes_reader->length()));
|
||||
upload_data_dict->Set("bytes", std::move(bytes));
|
||||
} else if (reader->AsFileReader()) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user